From 545506c923e69a2fd880de8a271270e7586ce306 Mon Sep 17 00:00:00 2001 From: Vencislav Atanasov Date: Wed, 18 Dec 2024 23:35:19 +0200 Subject: [PATCH] New port: iPod Nano 4G MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, only the development bootloader can be built successfully. This is a part of the large iPod Nano 3G and iPod Nano 4G support patch. Credit: Cástor Muñoz Change-Id: I74ea0da999ddb1d8ce5d0f5434141b3f0b5f7448 --- firmware/SOURCES | 21 + firmware/drivers/usb-designware.c | 2 +- firmware/export/config.h | 2 + firmware/export/config/ipodnano4g.h | 271 ++++++++ .../arm/s5l8702/ipodnano4g/adc-nano4g.c | 46 ++ .../arm/s5l8702/ipodnano4g/adc-target.h | 43 ++ .../arm/s5l8702/ipodnano4g/audio-nano4g.c | 77 +++ .../arm/s5l8702/ipodnano4g/backlight-nano4g.c | 67 ++ .../arm/s5l8702/ipodnano4g/backlight-target.h | 31 + .../arm/s5l8702/ipodnano4g/button-target.h | 76 +++ .../arm/s5l8702/ipodnano4g/cscodec-nano4g.c | 68 ++ .../arm/s5l8702/ipodnano4g/lcd-nano4g.c | 605 ++++++++++++++++++ .../arm/s5l8702/ipodnano4g/lcd-target.h | 34 + .../arm/s5l8702/ipodnano4g/nand-nano4g.c | 63 ++ .../arm/s5l8702/ipodnano4g/piezo-nano4g.c | 133 ++++ .../target/arm/s5l8702/ipodnano4g/piezo.h | 37 ++ .../arm/s5l8702/ipodnano4g/pmu-nano4g.c | 388 +++++++++++ .../arm/s5l8702/ipodnano4g/pmu-target.h | 161 +++++ .../arm/s5l8702/ipodnano4g/power-nano4g.c | 70 ++ .../arm/s5l8702/ipodnano4g/powermgmt-nano4g.c | 81 +++ .../arm/s5l8702/ipodnano4g/rtc-nano4g.c | 73 +++ .../arm/s5l8702/ipodnano4g/serial-nano4g.c | 249 +++++++ tools/configure | 109 ++-- tools/scramble.c | 4 +- 24 files changed, 2666 insertions(+), 45 deletions(-) create mode 100644 firmware/export/config/ipodnano4g.h create mode 100644 firmware/target/arm/s5l8702/ipodnano4g/adc-nano4g.c create mode 100644 firmware/target/arm/s5l8702/ipodnano4g/adc-target.h create mode 100644 firmware/target/arm/s5l8702/ipodnano4g/audio-nano4g.c create mode 100644 firmware/target/arm/s5l8702/ipodnano4g/backlight-nano4g.c create mode 100644 firmware/target/arm/s5l8702/ipodnano4g/backlight-target.h create mode 100644 firmware/target/arm/s5l8702/ipodnano4g/button-target.h create mode 100644 firmware/target/arm/s5l8702/ipodnano4g/cscodec-nano4g.c create mode 100644 firmware/target/arm/s5l8702/ipodnano4g/lcd-nano4g.c create mode 100644 firmware/target/arm/s5l8702/ipodnano4g/lcd-target.h create mode 100644 firmware/target/arm/s5l8702/ipodnano4g/nand-nano4g.c create mode 100644 firmware/target/arm/s5l8702/ipodnano4g/piezo-nano4g.c create mode 100644 firmware/target/arm/s5l8702/ipodnano4g/piezo.h create mode 100644 firmware/target/arm/s5l8702/ipodnano4g/pmu-nano4g.c create mode 100644 firmware/target/arm/s5l8702/ipodnano4g/pmu-target.h create mode 100644 firmware/target/arm/s5l8702/ipodnano4g/power-nano4g.c create mode 100644 firmware/target/arm/s5l8702/ipodnano4g/powermgmt-nano4g.c create mode 100644 firmware/target/arm/s5l8702/ipodnano4g/rtc-nano4g.c create mode 100644 firmware/target/arm/s5l8702/ipodnano4g/serial-nano4g.c diff --git a/firmware/SOURCES b/firmware/SOURCES index c78b030cc7..7b8991cf3e 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -1625,6 +1625,27 @@ target/arm/s5l8702/ipodnano3g/cscodec-nano3g.c // TODO: -> wmcodec-nano #endif #endif /* IPOD_NANO3G */ +#ifdef IPOD_NANO4G +target/arm/s5l8702/ipodnano4g/lcd-nano4g.c +target/arm/s5l8702/ipodnano4g/backlight-nano4g.c +target/arm/s5l8702/ipodnano4g/piezo-nano4g.c +target/arm/s5l8702/ipodnano4g/pmu-nano4g.c +target/arm/s5l8702/ipodnano4g/adc-nano4g.c +target/arm/s5l8702/ipodnano4g/powermgmt-nano4g.c +target/arm/s5l8702/ipodnano4g/power-nano4g.c +target/arm/s5l8702/ipodnano4g/nand-nano4g.c +#if (CONFIG_RTC == RTC_NANO4G) +target/arm/s5l8702/ipodnano4g/rtc-nano4g.c +#endif +#ifdef HAVE_SERIAL +target/arm/s5l8702/ipodnano4g/serial-nano4g.c +#endif +#ifndef BOOTLOADER +target/arm/s5l8702/ipodnano4g/audio-nano4g.c +target/arm/s5l8702/ipodnano4g/cscodec-nano4g.c +#endif +#endif /* IPOD_NANO4G */ + #ifdef IPOD_6G target/arm/s5l8702/ipod6g/lcd-6g.c target/arm/s5l8702/ipod6g/backlight-6g.c diff --git a/firmware/drivers/usb-designware.c b/firmware/drivers/usb-designware.c index 862445f2e8..a5a7a9b099 100644 --- a/firmware/drivers/usb-designware.c +++ b/firmware/drivers/usb-designware.c @@ -73,7 +73,7 @@ #elif CONFIG_CPU == S5L8701 # define USB_DW_PHYSADDR(x) x # define NO_UNCACHED_ADDR /* Not known how to form uncached addresses */ -#elif CONFIG_CPU == S5L8702 +#elif CONFIG_CPU == S5L8702 || CONFIG_CPU == S5L8720 # define USB_DW_PHYSADDR(x) S5L8702_PHYSICAL_ADDR(x) # define USB_DW_UNCACHEDADDR(x) S5L8702_UNCACHED_ADDR(x) #elif !defined(USB_DW_ARCH_SLAVE) diff --git a/firmware/export/config.h b/firmware/export/config.h index eddd2ea019..8ac710267b 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h @@ -422,6 +422,8 @@ Lyre prototype 1 */ #include "config/ipodnano2g.h" #elif defined(IPOD_NANO3G) #include "config/ipodnano3g.h" +#elif defined(IPOD_NANO4G) +#include "config/ipodnano4g.h" #elif defined(IPOD_6G) #include "config/ipod6g.h" #elif defined(GIGABEAT_F) diff --git a/firmware/export/config/ipodnano4g.h b/firmware/export/config/ipodnano4g.h new file mode 100644 index 0000000000..ec9a8ca53c --- /dev/null +++ b/firmware/export/config/ipodnano4g.h @@ -0,0 +1,271 @@ +/* + * This config file is for iPod Nano 4th Generation + */ + +#define IPOD_ARCH 1 + +/* For Rolo and boot loader */ +#define MODEL_NUMBER 118 + +#define MODEL_NAME "Apple iPod Nano 4G" + +/* define this if you have recording possibility */ +#define HAVE_RECORDING +//#define HAVE_AGC +//#define HAVE_HISTOGRAM + +/* Define bitmask of input sources - recordable bitmask can be defined + explicitly if different */ +#define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_LINEIN) + +/* define the bitmask of hardware sample rates */ +#define HW_SAMPR_CAPS (SAMPR_CAP_44 | SAMPR_CAP_22 | SAMPR_CAP_11 \ + | SAMPR_CAP_48 | SAMPR_CAP_24 | SAMPR_CAP_12 \ + | SAMPR_CAP_32 | SAMPR_CAP_16 | SAMPR_CAP_8) + +/* define the bitmask of recording sample rates */ +#define REC_SAMPR_CAPS (SAMPR_CAP_44 | SAMPR_CAP_22 | SAMPR_CAP_11 \ + | SAMPR_CAP_48 | SAMPR_CAP_24 | SAMPR_CAP_12 \ + | SAMPR_CAP_32 | SAMPR_CAP_16 | SAMPR_CAP_8) + +/* define this if you have a bitmap LCD display */ +#define HAVE_LCD_BITMAP + +/* define this if you can flip your LCD */ +//#define HAVE_LCD_FLIP + +/* define this if you have a colour LCD */ +#define HAVE_LCD_COLOR + +/* define this if you want album art for this target */ +#define HAVE_ALBUMART + +/* define this to enable bitmap scaling */ +#define HAVE_BMP_SCALING + +/* define this to enable JPEG decoding */ +#define HAVE_JPEG + +/* define this if you can invert the colours on your LCD */ +//#define HAVE_LCD_INVERT + +/* Define this if your LCD can set contrast */ +//#define HAVE_LCD_CONTRAST + +/* LCD stays visible without backlight - simulator hint */ +#define HAVE_TRANSFLECTIVE_LCD + +/* define this if you have access to the quickscreen */ +#define HAVE_QUICKSCREEN + +/* define this if you would like tagcache to build on this target */ +#define HAVE_TAGCACHE + +/* define this if the unit uses a scrollwheel for navigation */ +#define HAVE_SCROLLWHEEL +#define HAVE_WHEEL_ACCELERATION +#define WHEEL_ACCEL_START 270 +#define WHEEL_ACCELERATION 3 + +/* Define this if you can read an absolute wheel position */ +#define HAVE_WHEEL_POSITION + +#define CONFIG_KEYPAD IPOD_4G_PAD + +/* Define this if you can detect headphones */ +#define HAVE_HEADPHONE_DETECTION + +/* define this if you have a flash memory storage */ +#define HAVE_FLASH_STORAGE + +#define CONFIG_STORAGE STORAGE_NAND + +// TODO +//#define CONFIG_NAND NAND_SAMSUNG +#define CONFIG_NAND 0 + +/* define this if at least one storage driver + needs to do cleanup on shutdown */ +#define HAVE_STORAGE_FLUSH + +/* The NAND flash has 2048-byte sectors, and is our only storage */ +#define SECTOR_SIZE 2048 + +/* LCD dimensions */ +#define LCD_WIDTH 240 +#define LCD_HEIGHT 320 +/* sqrt(320^2 + 240^2) / 2.5 = 160.0 */ +#define LCD_DPI 160 +#define LCD_DEPTH 16 /* pseudo 262.144 colors */ +#define LCD_PIXELFORMAT RGB565 /* rgb565 */ + +/* Define this if the LCD can shut down */ +#define HAVE_LCD_SHUTDOWN + +/* Define this if your LCD can be enabled/disabled */ +//#define HAVE_LCD_ENABLE + +/* Define this if your LCD can be put to sleep. HAVE_LCD_ENABLE + should be defined as well. */ +#ifndef BOOTLOADER +#define HAVE_LCD_SLEEP +#define HAVE_LCD_SLEEP_SETTING +#endif +#define HAVE_LCD_SLEEP + +/* Define this to have CPU boosted while scrolling in the UI */ +#define HAVE_GUI_BOOST + +#define AB_REPEAT_ENABLE +#define ACTION_WPSAB_SINGLE ACTION_WPS_BROWSE + +/* Define this to enable morse code input */ +#define HAVE_MORSE_INPUT + +/* Define this if you do software codec */ +#define CONFIG_CODEC SWCODEC + +// TODO +/* define this if you have a real-time clock */ +//#define CONFIG_RTC RTC_NANO3G +#define CONFIG_RTC 0 + +/* Define if the device can wake from an RTC alarm */ +//#define HAVE_RTC_ALARM + +#define CONFIG_LCD LCD_IPOD6GNANO3G4G + +// TODO +/* Define the type of audio codec */ +#define HAVE_CS42L55 /* CS42L58 */ + +#define HAVE_PCM_DMA_ADDRESS + +/* Define this for LCD backlight available */ +#define HAVE_BACKLIGHT +#define HAVE_BACKLIGHT_BRIGHTNESS + +/* Define this if you have a software controlled poweroff */ +#define HAVE_SW_POWEROFF + +/* The number of bytes reserved for loadable codecs */ +#define CODEC_SIZE 0x100000 + +/* The number of bytes reserved for loadable plugins */ +#define PLUGIN_BUFFER_SIZE 0x80000 + +// TODO: actually these are the nano2g defines +#define BATTERY_CAPACITY_DEFAULT 400 /* default battery capacity */ +#define BATTERY_CAPACITY_MIN 300 /* min. capacity selectable */ +#define BATTERY_CAPACITY_MAX 500 /* max. capacity selectable */ +#define BATTERY_CAPACITY_INC 10 /* capacity increment */ +#define BATTERY_TYPES_COUNT 1 /* only one type */ + +#define CONFIG_BATTERY_MEASURE VOLTAGE_MEASURE + +/* Hardware controlled charging with monitoring */ +#define CONFIG_CHARGING CHARGING_MONITOR + +/* define current usage levels */ +#define CURRENT_NORMAL 17 /* playback @48MHz clock, backlight off */ +#define CURRENT_BACKLIGHT 23 /* maximum brightness */ + +/* define this if the unit can be powered or charged via USB */ +#define HAVE_USB_POWER + +#define HAVE_USB_CHARGING_ENABLE + +/* define this if the hardware can be powered off while charging */ +#define HAVE_POWEROFF_WHILE_CHARGING + +/* Define Apple remote tuner */ +//#define CONFIG_TUNER IPOD_REMOTE_TUNER +//#define HAVE_RDS_CAP +//#define CONFIG_RDS RDS_CFG_PUSH + +/* The exact type of CPU */ +#define CONFIG_CPU S5L8720 + +/* Define this to the CPU frequency */ +#define CPU_FREQ 266000000 // TODO: TBC + +/* Define this if you have adjustable CPU frequency */ +#define HAVE_ADJUSTABLE_CPU_FREQ + +/* I2C interface */ +#define CONFIG_I2C I2C_S5L8702 + +/* The size of the flash ROM */ +#define FLASH_SIZE 0x100000 + +/* Offset ( in the firmware file's header ) to the file CRC */ +#define FIRMWARE_OFFSET_FILE_CRC 0 + +/* Offset ( in the firmware file's header ) to the real data */ +#define FIRMWARE_OFFSET_FILE_DATA 8 + +#define BOOTFILE_EXT "ipod" +#define BOOTFILE "rockbox." BOOTFILE_EXT +#define BOOTDIR "/.rockbox" + +#define HAVE_HARDWARE_CLICK + +/* Define this for FM radio input available */ +#define HAVE_FMRADIO_IN + +/** Port-specific settings **/ + +#if 0 +/* Main LCD contrast range and defaults */ +#define MIN_CONTRAST_SETTING 1 +#define MAX_CONTRAST_SETTING 30 +#define DEFAULT_CONTRAST_SETTING 19 /* Match boot contrast */ +#endif + +/* Main LCD backlight brightness range and defaults */ +#define MIN_BRIGHTNESS_SETTING 1 +#define MAX_BRIGHTNESS_SETTING 0x3f +#define DEFAULT_BRIGHTNESS_SETTING 0x20 + +/* USB */ +#define CONFIG_USBOTG USBOTG_DESIGNWARE +#define USB_DW_CLOCK 0 +#define USB_DW_TURNAROUND 5 +/* logf() over USB serial (http://www.rockbox.org/wiki/PortalPlayerUsb) */ +//#define USB_ENABLE_SERIAL +#define HAVE_USBSTACK +#define HAVE_USB_HID_MOUSE +#define USB_VENDOR_ID 0x05AC +#define USB_PRODUCT_ID 0x1263 +#define USB_DEVBSS_ATTR __attribute__((aligned(32))) +// TODO +//#define HAVE_BOOTLOADER_USB_MODE +#ifdef BOOTLOADER +#define USBPOWER_BTN_IGNORE (~0) +#endif + +#define USB_READ_BUFFER_SIZE (1024*24) + +/* Serial */ +#ifdef BOOTLOADER +#if 0 /* Enable/disable LOGF_SERIAL for bootloader */ +#define HAVE_SERIAL +#define ROCKBOX_HAS_LOGF +#define LOGF_SERIAL +#endif +#else /* !BOOTLOADER */ +#define HAVE_SERIAL +/* Disable iAP when LOGF_SERIAL is enabled to avoid conflicts */ +#ifndef LOGF_SERIAL +#define IPOD_ACCESSORY_PROTOCOL +#endif +#endif + +/* Define this if you can switch on/off the accessory power supply */ +#define HAVE_ACCESSORY_SUPPLY + +/* Define this, if you can switch on/off the lineout */ +#define HAVE_LINEOUT_POWEROFF + +/* Define this if a programmable hotkey is mapped */ +#define HAVE_HOTKEY diff --git a/firmware/target/arm/s5l8702/ipodnano4g/adc-nano4g.c b/firmware/target/arm/s5l8702/ipodnano4g/adc-nano4g.c new file mode 100644 index 0000000000..24a2bc88e9 --- /dev/null +++ b/firmware/target/arm/s5l8702/ipodnano4g/adc-nano4g.c @@ -0,0 +1,46 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: adc-s5l8700.c 21775 2009-07-11 14:12:02Z bertrik $ + * + * Copyright (C) 2009 by Bertrik Sikken + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "config.h" + +#include "inttypes.h" +#include "s5l87xx.h" +#include "adc.h" +#include "adc-target.h" +#include "pmu-target.h" +#include "kernel.h" + +/* Returns battery voltage [millivolts] */ +unsigned int adc_read_battery_voltage(void) +{ + return 0; +} + +/* API functions */ +unsigned short adc_read(int channel) +{ + (void) channel; + return 0; +} + +void adc_init(void) +{ +} diff --git a/firmware/target/arm/s5l8702/ipodnano4g/adc-target.h b/firmware/target/arm/s5l8702/ipodnano4g/adc-target.h new file mode 100644 index 0000000000..bedc0a8447 --- /dev/null +++ b/firmware/target/arm/s5l8702/ipodnano4g/adc-target.h @@ -0,0 +1,43 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: adc-target.h 21734 2009-07-09 20:17:47Z bertrik $ + * + * Copyright (C) 2006 by Barry Wardell + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef _ADC_TARGET_H_ +#define _ADC_TARGET_H_ + +#include +#include "config.h" + +enum +{ + ADC_BATTERY = 0, + ADC_USBDATA, + ADC_ACCESSORY, + NUM_ADC_CHANNELS +}; + +#define ADC_UNREG_POWER ADC_BATTERY /* For compatibility */ + +unsigned short adc_read_millivolts(int channel); +unsigned int adc_read_battery_voltage(void); +unsigned int adc_read_usbdata_voltage(bool dp); +int adc_read_accessory_resistor(void); +const char *adc_name(int channel); + +#endif diff --git a/firmware/target/arm/s5l8702/ipodnano4g/audio-nano4g.c b/firmware/target/arm/s5l8702/ipodnano4g/audio-nano4g.c new file mode 100644 index 0000000000..fc49ec6316 --- /dev/null +++ b/firmware/target/arm/s5l8702/ipodnano4g/audio-nano4g.c @@ -0,0 +1,77 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: audio-nano2g.c 23095 2009-10-11 09:17:12Z dave $ + * + * Copyright (C) 2006 by Michael Sevakis + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "system.h" +#include "cpu.h" +#include "audio.h" +#include "sound.h" + + +#if INPUT_SRC_CAPS != 0 +void audio_set_output_source(int source) +{ + if ((unsigned)source >= AUDIO_NUM_SOURCES) + source = AUDIO_SRC_PLAYBACK; +} /* audio_set_output_source */ + +void audio_input_mux(int source, unsigned flags) +{ + (void)flags; + /* Prevent pops from unneeded switching */ + static int last_source = AUDIO_SRC_PLAYBACK; + + switch (source) + { + default: /* playback - no recording */ + source = AUDIO_SRC_PLAYBACK; + case AUDIO_SRC_PLAYBACK: +#ifdef HAVE_RECORDING + if (source != last_source) + { + audiohw_set_monitor(false); + audiohw_disable_recording(); + } +#endif + break; + +#ifdef HAVE_MIC_REC + case AUDIO_SRC_MIC: /* recording only */ + if (source != last_source) + { + audiohw_set_monitor(false); + audiohw_enable_recording(true); /* source mic */ + } + break; +#endif + +#ifdef HAVE_LINE_REC + case AUDIO_SRC_LINEIN: /* recording only */ + if (source != last_source) + { + audiohw_set_monitor(false); + audiohw_enable_recording(false); /* source line */ + } + break; +#endif + } /* end switch */ + + last_source = source; +} /* audio_input_mux */ +#endif /* INPUT_SRC_CAPS != 0 */ diff --git a/firmware/target/arm/s5l8702/ipodnano4g/backlight-nano4g.c b/firmware/target/arm/s5l8702/ipodnano4g/backlight-nano4g.c new file mode 100644 index 0000000000..b98fa29f75 --- /dev/null +++ b/firmware/target/arm/s5l8702/ipodnano4g/backlight-nano4g.c @@ -0,0 +1,67 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: backlight-nano2g.c 28601 2010-11-14 20:39:18Z theseven $ + * + * Copyright (C) 2009 by Dave Chapman + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include + +#include "config.h" +#include "kernel.h" +#include "backlight.h" +#include "backlight-target.h" +#include "pmu-target.h" + +#ifdef HAVE_LCD_SLEEP +#include "lcd.h" +#include "lcd-s5l8702.h" +#endif + + +void backlight_hw_brightness(int brightness) +{ + pmu_write(D1759_REG_LEDOUT, brightness << 2); +} + +void backlight_hw_on(void) +{ +#ifdef HAVE_LCD_SLEEP + if (!lcd_active()) + lcd_awake(); +#endif + pmu_write(D1759_REG_LEDCTL, + (pmu_read(D1759_REG_LEDCTL) | D1759_LEDCTL_ENABLE)); +} + +void backlight_hw_off(void) +{ + pmu_write(D1759_REG_LEDCTL, + (pmu_read(D1759_REG_LEDCTL) & ~D1759_LEDCTL_ENABLE)); +} + +bool backlight_hw_init(void) +{ + backlight_hw_brightness(DEFAULT_BRIGHTNESS_SETTING); + backlight_hw_on(); + return true; +} + +/* Kill the backlight, instantly. */ +void backlight_hw_kill(void) +{ + backlight_hw_off(); +} diff --git a/firmware/target/arm/s5l8702/ipodnano4g/backlight-target.h b/firmware/target/arm/s5l8702/ipodnano4g/backlight-target.h new file mode 100644 index 0000000000..89ed552b2e --- /dev/null +++ b/firmware/target/arm/s5l8702/ipodnano4g/backlight-target.h @@ -0,0 +1,31 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: backlight-target.h 21478 2009-06-23 18:11:03Z bertrik $ + * + * Copyright (C) 2008 by Marcoen Hirschberg + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef BACKLIGHT_TARGET_H +#define BACKLIGHT_TARGET_H + +bool backlight_hw_init(void); +void backlight_hw_on(void); +void backlight_hw_off(void); +void backlight_hw_brightness(int brightness); + +void backlight_hw_kill(void); + +#endif diff --git a/firmware/target/arm/s5l8702/ipodnano4g/button-target.h b/firmware/target/arm/s5l8702/ipodnano4g/button-target.h new file mode 100644 index 0000000000..a5c4771b7c --- /dev/null +++ b/firmware/target/arm/s5l8702/ipodnano4g/button-target.h @@ -0,0 +1,76 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: button-target.h 21828 2009-07-12 22:16:51Z dave $ + * + * Copyright (C) 2006 by Barry Wardell + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef _BUTTON_TARGET_H_ +#define _BUTTON_TARGET_H_ + +#include "config.h" + +#define HAS_BUTTON_HOLD + +void ipod_mini_button_int(void); +void ipod_3g_button_int(void); +void ipod_4g_button_int(void); + +/* iPod specific button codes */ + +#define BUTTON_SELECT 0x00000001 +#define BUTTON_MENU 0x00000002 + +#define BUTTON_LEFT 0x00000004 +#define BUTTON_RIGHT 0x00000008 +#define BUTTON_SCROLL_FWD 0x00000010 +#define BUTTON_SCROLL_BACK 0x00000020 + +#define BUTTON_PLAY 0x00000040 + +#define BUTTON_MAIN (BUTTON_SELECT|BUTTON_MENU\ + |BUTTON_LEFT|BUTTON_RIGHT|BUTTON_SCROLL_FWD\ + |BUTTON_SCROLL_BACK|BUTTON_PLAY) + + /* Remote control's buttons */ +#ifdef IPOD_ACCESSORY_PROTOCOL +#define BUTTON_RC_DOWN 0x01000000 +#define BUTTON_RC_UP 0x00800000 +#define BUTTON_RC_SELECT 0x00400000 +#define BUTTON_RC_MENU 0x00200000 +#define BUTTON_RC_PLAY 0x00100000 +#define BUTTON_RC_STOP 0x00080000 +#define BUTTON_RC_LEFT 0x00040000 +#define BUTTON_RC_RIGHT 0x00020000 +#define BUTTON_RC_VOL_UP 0x00010000 +#define BUTTON_RC_VOL_DOWN 0x00008000 + +#define BUTTON_REMOTE (BUTTON_RC_UP|BUTTON_RC_DOWN \ + |BUTTON_RC_SELECT|BUTTON_RC_PLAY \ + |BUTTON_RC_PLAY|BUTTON_RC_STOP \ + |BUTTON_RC_LEFT|BUTTON_RC_RIGHT\ + |BUTTON_RC_VOL_UP|BUTTON_RC_VOL_DOWN) +#endif + +/* This is for later +#define BUTTON_SCROLL_TOUCH 0x00000200 +*/ + + +#define POWEROFF_BUTTON BUTTON_PLAY +#define POWEROFF_COUNT 40 + +#endif /* _BUTTON_TARGET_H_ */ diff --git a/firmware/target/arm/s5l8702/ipodnano4g/cscodec-nano4g.c b/firmware/target/arm/s5l8702/ipodnano4g/cscodec-nano4g.c new file mode 100644 index 0000000000..9daca61f5c --- /dev/null +++ b/firmware/target/arm/s5l8702/ipodnano4g/cscodec-nano4g.c @@ -0,0 +1,68 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: wmcodec-s5l8700.c 22025 2009-07-25 00:49:13Z dave $ + * + * S5L8702-specific code for Cirrus codecs + * + * Copyright (c) 2010 Michael Sparmann + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "system.h" +#include "audiohw.h" +#include "i2c-s5l8702.h" +#include "s5l87xx.h" +#include "cscodec.h" + +void audiohw_init(void) +{ +#ifdef HAVE_CS42L55 + audiohw_preinit(); +#endif +} + +unsigned char cscodec_read(int reg) +{ + // TODO: not tested + unsigned char data; + i2c_read(0, 0x94, reg, 1, &data); + return data; +} + +void cscodec_write(int reg, unsigned char data) +{ + // TODO: not tested + i2c_write(0, 0x94, reg, 1, &data); +} + +void cscodec_power(bool state) +{ + (void)state; //TODO: Figure out which LDO this is +} + +void cscodec_reset(bool state) +{ + // TODO: not tested + // if (state) PDAT(3) &= ~8; + // else PDAT(3) |= 8; +} + +void cscodec_clock(bool state) +{ + // TODO: not tested + if (state) CLKCON3 &= ~0xffff; + else CLKCON3 |= 0x8000; +} diff --git a/firmware/target/arm/s5l8702/ipodnano4g/lcd-nano4g.c b/firmware/target/arm/s5l8702/ipodnano4g/lcd-nano4g.c new file mode 100644 index 0000000000..2d419571c8 --- /dev/null +++ b/firmware/target/arm/s5l8702/ipodnano4g/lcd-nano4g.c @@ -0,0 +1,605 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: + * + * Copyright (C) 2017 Cástor Muñoz + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include +#include "config.h" + +#include "lcd-s5l8702.h" +#ifdef BOOTLOADER +#include "piezo.h" +#endif + +// XXX: For nano3g displays see ili9327, which says it supports 8-bit MIDI interface command and 8-bit param + +#if defined(HAVE_LCD_SLEEP) || defined(HAVE_LCD_SHUTDOWN) +/* powersave sequences */ + +/* 0xb3, 0xe6 */ +static const uint8_t lcd_sleep_seq_03[] = +{ + // XXX: MARK 3 + CMD, 0x28, 0, /* Display Off */ + CMD, 0x10, 0, /* Sleep In */ + SLEEP, 5, /* 50 ms */ + END +}; + +/* 0xc4 */ +static const uint8_t lcd_sleep_seq_1[] = +{ + // XXX: MARK 3 + CMD, 0x28, 0, /* Display Off */ + CMD, 0x10, 0, /* Sleep In */ + SLEEP, 12, /* 120 ms */ + END +}; + +/* 0xd5 */ +static const uint8_t lcd_sleep_seq_2[] = +{ + // XXX: MARK 3 + CMD, 0x10, 0, /* Sleep In */ + END +}; +#endif /* HAVE_LCD_SLEEP || HAVE_LCD_SHUTDOWN */ + + +#if defined(HAVE_LCD_SLEEP) +/* awake sequences */ + +/* 0xb3, 0xc4, 0xd5, 0xe6 */ +static const uint8_t lcd_awake_seq_0123[] = +{ + CMD, 0x11, 0, /* Sleep Out */ + SLEEP, 12, /* 120 ms */ + CMD, 0x29, 0, /* Display On */ + SLEEP, 1, /* 10 ms */ + END +}; +#endif /* HAVE_LCD_SLEEP */ + + +#if defined(BOOTLOADER) +/* init sequences */ +// TODO: put something else at the end of the init sequence???, the bootloader without a sleep is very tight () + +/* 0xb3 */ +static const uint8_t lcd_init_seq_0[] = +{ + #if 1 + CMD, 0x11, 0, /* Sleep Out */ + SLEEP, 12, /* 120 ms */ + + CMD, 0xfe, 1, 0x00, // XXX: This and the above do not make much sense, see nano3g + CMD, 0xef, 1, 0x80, + + /* Power control */ + CMD, 0xc0, 1, 0x0c, + CMD, 0xc1, 1, 0x03, + CMD, 0xc2, 2, 0x12, 0x00, + CMD, 0xc3, 2, 0x12, 0x00, + CMD, 0xc4, 2, 0x12, 0x00, + CMD, 0xc5, 2, 0x3a, 0x3e, + + /* Display control */ + CMD, 0xb1, 2, 0x6a, 0x15, + CMD, 0xb2, 2, 0x5f, 0x3f, + CMD, 0xb3, 2, 0x5f, 0x3f, + CMD, 0xb4, 1, 0x02, + CMD, 0xb6, 2, 0x12, 0x02, + + CMD, 0x35, 1, 0x00, /* Tearing Effect Line On */ + CMD, 0x26, 1, 0x10, /* Gamma Set */ + + /* Gamma settings */ + CMD, 0xe0, 11, 0x0f, 0x42, 0x24, 0x01, 0x00, 0x02, 0xa6, 0x98, + 0x05, 0x04, 0x15, + CMD, 0xe1, 11, 0x00, 0x21, 0x44, 0x02, 0x0f, 0x05, 0x89, 0x6a, + 0x02, 0x15, 0x04, + CMD, 0xe2, 11, 0x7e, 0x04, 0x43, 0x40, 0x00, 0x02, 0x13, 0x00, + 0x00, 0x01, 0x0b, + CMD, 0xe3, 11, 0x40, 0x40, 0x03, 0x74, 0x0e, 0x00, 0x00, 0x31, + 0x02, 0x0b, 0x01, + CMD, 0xe4, 11, 0x5a, 0x43, 0x67, 0x56, 0x00, 0x02, 0x67, 0x72, + 0x00, 0x05, 0x12, + CMD, 0xe5, 11, 0x50, 0x66, 0x47, 0x53, 0x0a, 0x00, 0x27, 0x76, + 0x02, 0x12, 0x05, + + CMD, 0x3a, 1, 0x06, /* Pixel Format Set */ + CMD, 0x13, 0, /* Normal Mode On */ + + // XXX: MARK3 + + CMD, 0x29, 0, /* Display On */ + SLEEP, 1, /* 10 ms */ // orig: 0x1 -> 1ms ??? + END + #else + + CMD, 0xef, 1, 0x80, // ILI9340: XXX: does not exist + + /* Power control */ + CMD, 0xc0, 1, 0x06, + CMD, 0xc1, 1, 0x03, + CMD, 0xc2, 2, 0x12, 0x00, + CMD, 0xc3, 2, 0x12, 0x00, + CMD, 0xc4, 2, 0x12, 0x00, + CMD, 0xc5, 2, 0x40, 0x38, + + /* Display control */ + CMD, 0xb1, 2, 0x5f, 0x3f, + CMD, 0xb2, 2, 0x5f, 0x3f, + CMD, 0xb3, 2, 0x5f, 0x3f, + CMD, 0xb4, 1, 0x02, + CMD, 0xb6, 2, 0x12, 0x02, + + CMD, 0x35, 1, 0x00, /* Tearing Effect Line On */ + CMD, 0x26, 1, 0x10, /* Gamma Set */ + + CMD, 0xfe, 1, 0x00, // ILI9340: XXX: does not exist + + /* Gamma settings */ + CMD, 0xe0, 11, 0x0f, 0x70, 0x47, 0x03, 0x02, 0x02, 0xa0, 0x94, + 0x05, 0x00, 0x0e, + CMD, 0xe1, 11, 0x02, 0x43, 0x77, 0x00, 0x0f, 0x05, 0x49, 0x0a, + 0x02, 0x0e, 0x00, + CMD, 0xe2, 11, 0x2f, 0x63, 0x20, 0x50, 0x00, 0x07, 0xd1, 0x13, + 0x00, 0x00, 0x0e, + CMD, 0xe3, 11, 0x50, 0x20, 0x60, 0x23, 0x0f, 0x00, 0x31, 0x1d, + 0x07, 0x0e, 0x00, + CMD, 0xe4, 11, 0x5e, 0x50, 0x65, 0x27, 0x00, 0x0b, 0xdf, 0xf1, + 0x01, 0x00, 0x0e, + CMD, 0xe5, 11, 0x20, 0x67, 0x55, 0x50, 0x0e, 0x01, 0x1f, 0xfd, + 0x0b, 0x0e, 0x00, + + CMD, 0x3a, 1, 0x06, /* Pixel Format Set */ // XXX: 110b -> 18-bit / pixel + CMD, 0x36, 1, 0x60, /* Memory Access Control */ + CMD, 0x13, 0, /* Normal Mode On */ + + // XXX: MARK 3 + +// CMD, 0x29, 0, /* Display On */ +// SLEEP, 1, /* 10 ms */ // orig: 0x1 -> 1ms ??? + CMD, 0x11, 0, /* Sleep Out */ + SLEEP, 12, /* 120 ms */ // orig: 0x78 -> 120ms ??? + CMD, 0x29, 0, /* Display On */ + SLEEP, 1, /* 10 ms */ // orig: 0x1 -> 1ms ??? + END + #endif +}; + +/* 0xc4 */ +static const uint8_t lcd_init_seq_1[] = +{ + #if 1 + CMD, 0x01, 0, /* Software Reset */ + SLEEP, 1, /* 10 ms */ + + /* Power control */ + CMD, 0xc0, 1, 0x00, + CMD, 0xc1, 1, 0x03, + CMD, 0xc2, 2, 0x34, 0x00, + CMD, 0xc3, 2, 0x72, 0x03, + CMD, 0xc4, 2, 0x73, 0x03, + CMD, 0xc5, 2, 0x3c, 0x3c, + + CMD, 0xfe, 1, 0x00, + + /* Display control */ + CMD, 0xb1, 2, 0x6a, 0x15, + CMD, 0xb2, 2, 0x6a, 0x15, + CMD, 0xb3, 2, 0x6a, 0x15, + CMD, 0xb4, 1, 0x02, + CMD, 0xb6, 2, 0x12, 0x02, + + CMD, 0x35, 1, 0x00, /* Tearing Effect Line On */ + CMD, 0x26, 1, 0x10, /* Gamma Set */ + + /* Gamma settings */ + CMD, 0xe0, 11, 0x77, 0x52, 0x76, 0x53, 0x03, 0x03, 0x57, 0x42, + 0x10, 0x18, 0x09, + CMD, 0xe1, 11, 0x0d, 0x00, 0x23, 0x66, 0x0f, 0x15, 0x4d, 0x85, + 0x08, 0x02, 0x10, + CMD, 0xe2, 11, 0x39, 0x60, 0x77, 0x05, 0x03, 0x07, 0x96, 0x64, + 0x0d, 0x1a, 0x0a, + CMD, 0xe3, 11, 0x3f, 0x10, 0x16, 0x44, 0x0e, 0x04, 0x6c, 0x44, + 0x04, 0x03, 0x0b, + CMD, 0xe4, 11, 0x00, 0x61, 0x77, 0x04, 0x02, 0x04, 0x72, 0x32, + 0x09, 0x19, 0x06, + CMD, 0xe5, 11, 0x4f, 0x42, 0x27, 0x67, 0x0f, 0x02, 0x26, 0x33, + 0x01, 0x03, 0x09, + + CMD, 0x3a, 1, 0x66, /* Pixel Format Set */ + CMD, 0x36, 1, 0x00, /* Memory Access Control */ + + // XXX: MARK 3 + +// CMD, 0x29, 0, /* Display On */ +// SLEEP, 1, /* 10 ms */ + CMD, 0x11, 0, /* Sleep Out */ + SLEEP, 12, /* 120 ms */ // TODO: can be removed ??? + CMD, 0x29, 0, /* Display On */ + SLEEP, 1, /* 10 ms */ + END + + #else + CMD, 0x01, 0, /* Software Reset */ + SLEEP, 1, /* 10 ms */ + + /* Power control */ + CMD, 0xc0, 1, 0x01, + CMD, 0xc1, 1, 0x03, + CMD, 0xc2, 2, 0x74, 0x00, + CMD, 0xc3, 2, 0x72, 0x03, + CMD, 0xc4, 2, 0x73, 0x03, + CMD, 0xc5, 2, 0x3c, 0x3c, + + /* Display control */ + CMD, 0xb1, 2, 0x6a, 0x15, + CMD, 0xb2, 2, 0x6a, 0x15, + CMD, 0xb3, 2, 0x6a, 0x15, + CMD, 0xb4, 1, 0x02, + CMD, 0xb6, 2, 0x12, 0x02, + + CMD, 0x35, 1, 0x00, /* Tearing Effect Line On */ + CMD, 0x26, 1, 0x10, /* Gamma Set */ + + /* Gamma settings */ + CMD, 0xe0, 11, 0x1e, 0x22, 0x44, 0x00, 0x09, 0x01, 0x47, 0xc1, + 0x05, 0x02, 0x09, + CMD, 0xe1, 11, 0x0f, 0x32, 0x35, 0x00, 0x03, 0x05, 0x5e, 0x78, + 0x03, 0x00, 0x03, + CMD, 0xe2, 11, 0x0d, 0x74, 0x47, 0x41, 0x07, 0x01, 0x74, 0x41, + 0x09, 0x03, 0x07, + CMD, 0xe3, 11, 0x5f, 0x41, 0x27, 0x02, 0x00, 0x03, 0x43, 0x55, + 0x02, 0x00, 0x03, + CMD, 0xe4, 11, 0x1b, 0x53, 0x44, 0x51, 0x0b, 0x01, 0x64, 0x20, + 0x05, 0x02, 0x09, + CMD, 0xe5, 11, 0x7f, 0x41, 0x26, 0x02, 0x04, 0x00, 0x33, 0x35, + 0x01, 0x00, 0x02, + + CMD, 0x3a, 1, 0x66, /* Pixel Format Set */ + CMD, 0x36, 1, 0x60, /* Memory Access Control */ + + // XXX: MARK 3 + +// CMD, 0x29, 0, /* Display On */ +// SLEEP, 1, /* 10 ms */ + CMD, 0x11, 0, /* Sleep Out */ + SLEEP, 12, /* 120 ms */ + CMD, 0x29, 0, /* Display On */ + SLEEP, 1, /* 10 ms */ + END + #endif +}; + +/* 0xd5 */ +static const uint8_t lcd_init_seq_2[] = +{ + #if 1 + CMD, 0xfe, 1, 0x00, + + /* Power control */ + CMD, 0xc0, 1, 0x01, + CMD, 0xc1, 1, 0x01, + CMD, 0xc2, 2, 0x03, 0x00, + CMD, 0xc3, 2, 0x01, 0x00, + CMD, 0xc4, 2, 0x03, 0x00, + CMD, 0xc5, 2, 0x34, 0x34, + CMD, 0xc7, 1, 0x00, + + /* Display control */ + CMD, 0xb1, 2, 0x6d, 0x15, + CMD, 0xb2, 2, 0x6d, 0x15, + CMD, 0xb3, 2, 0x6d, 0x15, + CMD, 0xb4, 1, 0x03, + CMD, 0xb6, 2, 0x11, 0x02, + + CMD, 0x35, 1, 0x00, /* Tearing Effect Line On */ + CMD, 0x26, 1, 0x10, /* Gamma Set */ + + /* Gamma settings */ + CMD, 0xe0, 11, 0x23, 0x42, 0x20, 0x42, 0x0e, 0x01, 0xf5, 0xeb, + 0x13, 0x05, 0x18, + CMD, 0xe1, 11, 0x5f, 0x22, 0x36, 0x21, 0x03, 0x1e, 0xfe, 0x7b, + 0x02, 0x07, 0x18, + CMD, 0xe2, 11, 0x5f, 0x34, 0x53, 0x77, 0x0a, 0x00, 0x70, 0xf4, + 0x14, 0x06, 0x0f, + CMD, 0xe3, 11, 0x0f, 0x23, 0x31, 0x54, 0x0f, 0x0b, 0x8e, 0x08, + 0x00, 0x05, 0x15, + CMD, 0xe4, 11, 0x5f, 0x33, 0x42, 0x14, 0x0e, 0x04, 0xa6, 0xf7, + 0x0e, 0x00, 0x14, + CMD, 0xe5, 11, 0x0c, 0x43, 0x44, 0x44, 0x0d, 0x0d, 0x7f, 0x39, + 0x03, 0x02, 0x10, + + CMD, 0x3a, 1, 0x66, /* Pixel Format Set */ + CMD, 0x36, 1, 0x00, /* Memory Access Control */ + + // XXX: MARK 3 + + CMD, 0x29, 0, /* Display On */ + SLEEP, 1, /* 10 ms */ + CMD, 0x11, 0, /* Sleep Out */ + SLEEP, 12, /* 120 ms */ + END + + #else + CMD, 0xfe, 1, 0x00, // ILI9340: XXX: does not exist + + /* Power control */ + CMD, 0xc0, 1, 0x00, + CMD, 0xc1, 1, 0x03, + CMD, 0xc2, 2, 0x73, 0x03, + CMD, 0xc3, 2, 0x73, 0x03, + CMD, 0xc4, 2, 0x73, 0x03, + CMD, 0xc5, 2, 0x64, 0x37, + + /* Display control */ + CMD, 0xb1, 2, 0x69, 0x13, + CMD, 0xb2, 2, 0x69, 0x13, + CMD, 0xb3, 2, 0x69, 0x13, + CMD, 0xb4, 1, 0x02, + CMD, 0xb6, 2, 0x03, 0x12, + + CMD, 0x35, 1, 0x00, /* Tearing Effect Line On */ + CMD, 0x26, 1, 0x10, /* Gamma Set */ + + /* Gamma settings */ + CMD, 0xe0, 11, 0x08, 0x00, 0x10, 0x00, 0x03, 0x0e, 0xc8, 0x65, + 0x05, 0x00, 0x00, + CMD, 0xe1, 11, 0x06, 0x20, 0x00, 0x00, 0x00, 0x07, 0x4d, 0x0b, + 0x08, 0x00, 0x00, + CMD, 0xe2, 11, 0x08, 0x77, 0x27, 0x63, 0x0f, 0x16, 0xcf, 0x25, + 0x03, 0x00, 0x00, + CMD, 0xe3, 11, 0x5f, 0x53, 0x77, 0x06, 0x00, 0x02, 0x4b, 0x7b, + 0x0f, 0x00, 0x00, + CMD, 0xe4, 11, 0x08, 0x46, 0x57, 0x52, 0x0f, 0x16, 0xcf, 0x25, + 0x04, 0x00, 0x00, + CMD, 0xe5, 11, 0x6f, 0x44, 0x57, 0x06, 0x00, 0x04, 0x43, 0x7b, + 0x0f, 0x00, 0x00, + + CMD, 0x3a, 1, 0x66, /* Pixel Format Set */ + CMD, 0x36, 1, 0x60, /* Memory Access Control */ + + // XXX: MARK 3 + +// CMD, 0x29, 0, /* Display On */ +// SLEEP, 1, /* 10 ms */ + CMD, 0x11, 0, /* Sleep Out */ + SLEEP, 12, /* 120 ms */ + CMD, 0x29, 0, /* Display On */ + SLEEP, 1, /* 10 ms */ + END + #endif +}; + +/* 0xe6 */ +static const uint8_t lcd_init_seq_3[] = +{ + #if 1 + CMD, 0x11, 0, /* Sleep Out */ + SLEEP, 12, /* 120 ms */ + + CMD, 0xfe, 1, 0x00, + CMD, 0xef, 1, 0x80, + + /* Power control */ + CMD, 0xc0, 1, 0x13, + CMD, 0xc1, 1, 0x03, + CMD, 0xc2, 2, 0x12, 0x00, + CMD, 0xc3, 2, 0x12, 0x00, + CMD, 0xc4, 2, 0x12, 0x00, + CMD, 0xc5, 2, 0x2a, 0x3c, + + /* Display control */ + CMD, 0xb1, 2, 0x6a, 0x15, + CMD, 0xb2, 2, 0x5f, 0x3f, + CMD, 0xb3, 2, 0x5f, 0x3f, + CMD, 0xb4, 1, 0x02, + CMD, 0xb6, 2, 0x12, 0x02, + + CMD, 0x35, 1, 0x00, /* Tearing Effect Line On */ + CMD, 0x26, 1, 0x10, /* Gamma Set */ + + /* Gamma settings */ + CMD, 0xe0, 11, 0x0f, 0x53, 0x45, 0x07, 0x00, 0x00, 0xb9, 0xf6, + 0x08, 0x04, 0x18, + CMD, 0xe1, 11, 0x00, 0x47, 0x55, 0x03, 0x0f, 0x08, 0x6f, 0x9b, + 0x00, 0x18, 0x04, + CMD, 0xe2, 11, 0x7e, 0x03, 0x54, 0x75, 0x00, 0x00, 0x3a, 0x52, + 0x03, 0x02, 0x10, + CMD, 0xe3, 11, 0x70, 0x55, 0x04, 0x73, 0x0e, 0x03, 0x25, 0xa3, + 0x00, 0x10, 0x02, + CMD, 0xe4, 11, 0x1a, 0x72, 0x33, 0x76, 0x00, 0x00, 0xeb, 0x97, + 0x03, 0x05, 0x17, + CMD, 0xe5, 11, 0x70, 0x36, 0x73, 0x12, 0x0a, 0x03, 0x79, 0xbe, + 0x00, 0x17, 0x05, + + CMD, 0x3a, 1, 0x06, /* Pixel Format Set */ + CMD, 0x13, 0, /* Normal Mode On */ + + // XXX: MARK 3 + + CMD, 0x29, 0, /* Display On */ + SLEEP, 1, /* 10 ms */ + END +// CMD, 0x11, 0, /* Sleep Out */ +// SLEEP, 12, /* 120 ms */ +// CMD, 0x29, 0, /* Display On */ +// SLEEP, 1, /* 10 ms */ +// END + + #else + CMD, 0xef, 1, 0x80, // ILI9340: XXX: does not exist, enter privileged mode (to write 0xCx and 0xBx) ??? + + /* Power control */ + CMD, 0xc0, 1, 0x0a, + CMD, 0xc1, 1, 0x03, + CMD, 0xc2, 2, 0x12, 0x00, + CMD, 0xc3, 2, 0x12, 0x00, + CMD, 0xc4, 2, 0x12, 0x00, + CMD, 0xc5, 2, 0x38, 0x38, + + /* Display control */ + CMD, 0xb1, 2, 0x5f, 0x3f, + CMD, 0xb2, 2, 0x5f, 0x3f, + CMD, 0xb3, 2, 0x5f, 0x3f, + CMD, 0xb4, 1, 0x02, + CMD, 0xb6, 2, 0x12, 0x02, + + CMD, 0x35, 1, 0x00, /* Tearing Effect Line On */ + CMD, 0x26, 1, 0x10, /* Gamma Set */ + + CMD, 0xfe, 1, 0x00, // ILI9340: XXX: does not exist + + /* Gamma settings */ + CMD, 0xe0, 11, 0x0f, 0x70, 0x47, 0x03, 0x02, 0x02, 0xa0, 0x94, + 0x05, 0x00, 0x0e, + CMD, 0xe1, 11, 0x02, 0x43, 0x77, 0x00, 0x0f, 0x05, 0x49, 0x0a, + 0x02, 0x0e, 0x00, + CMD, 0xe2, 11, 0x2f, 0x63, 0x20, 0x50, 0x00, 0x07, 0xd1, 0x13, + 0x00, 0x00, 0x0e, + CMD, 0xe3, 11, 0x50, 0x20, 0x60, 0x23, 0x0f, 0x00, 0x31, 0x1d, + 0x07, 0x0e, 0x00, + CMD, 0xe4, 11, 0x5e, 0x50, 0x65, 0x27, 0x00, 0x0b, 0xdf, 0xf1, + 0x01, 0x00, 0x0e, + CMD, 0xe5, 11, 0x20, 0x67, 0x55, 0x50, 0x0e, 0x01, 0x1f, 0xfd, + 0x0b, 0x0e, 0x00, + + CMD, 0x3a, 1, 0x06, /* Pixel Format Set */ + CMD, 0x36, 1, 0x60, /* Memory Control Access */ + CMD, 0x13, 0, /* Normal Mode On */ + + // XXX: MARK 3 + +// CMD, 0x29, 0, /* Display On */ +// SLEEP, 1, /* 10 ms */ + CMD, 0x11, 0, /* Sleep Out */ + SLEEP, 12, /* 120 ms */ + CMD, 0x29, 0, /* Display On */ + SLEEP, 1, /* 10 ms */ + END + #endif +}; +#endif /* BOOTLOADER */ + + +/* Supported LCD types */ +enum { + LCD_TYPE_UNKNOWN = -1, + LCD_TYPE_B3 = 0, + LCD_TYPE_C4, + LCD_TYPE_D5, + LCD_TYPE_E6, + N_LCD_TYPES +}; + +static struct lcd_info_rec lcd_info_list[] = +{ + [LCD_TYPE_B3] = { + .lcd_type = LCD_TYPE_B3, + .mpuiface = LCD_MPUIFACE_SERIAL, + #if defined(HAVE_LCD_SLEEP) || defined(HAVE_LCD_SHUTDOWN) + .seq_sleep = (void*) lcd_sleep_seq_03, + #endif + #ifdef HAVE_LCD_SLEEP + .seq_awake = (void*) lcd_awake_seq_0123, + #endif + #ifdef BOOTLOADER + .seq_init = (void*) lcd_init_seq_0, + #endif + }, + + [LCD_TYPE_C4] = { + .lcd_type = LCD_TYPE_C4, + .mpuiface = LCD_MPUIFACE_SERIAL, + #if defined(HAVE_LCD_SLEEP) || defined(HAVE_LCD_SHUTDOWN) + .seq_sleep = (void*) lcd_sleep_seq_1, + #endif + #ifdef HAVE_LCD_SLEEP + .seq_awake = (void*) lcd_awake_seq_0123, + #endif + #ifdef BOOTLOADER + .seq_init = (void*) lcd_init_seq_1, + #endif + }, + + [LCD_TYPE_D5] = { + .lcd_type = LCD_TYPE_D5, + .mpuiface = LCD_MPUIFACE_SERIAL, + #if defined(HAVE_LCD_SLEEP) || defined(HAVE_LCD_SHUTDOWN) + .seq_sleep = (void*) lcd_sleep_seq_2, + #endif + #ifdef HAVE_LCD_SLEEP + .seq_awake = (void*) lcd_awake_seq_0123, + #endif + #ifdef BOOTLOADER + .seq_init = (void*) lcd_init_seq_2, + #endif + }, + + [LCD_TYPE_E6] = { + .lcd_type = LCD_TYPE_E6, + .mpuiface = LCD_MPUIFACE_SERIAL, + #if defined(HAVE_LCD_SLEEP) || defined(HAVE_LCD_SHUTDOWN) + .seq_sleep = (void*) lcd_sleep_seq_03, + #endif + #ifdef HAVE_LCD_SLEEP + .seq_awake = (void*) lcd_awake_seq_0123, + #endif + #ifdef BOOTLOADER + .seq_init = (void*) lcd_init_seq_3, + #endif + }, +}; + +uint8_t lcd_id[4]; // XXX: DEBUG + +struct lcd_info_rec* lcd_target_get_info(void) +{ + // uint8_t lcd_id[4]; + int type = LCD_TYPE_UNKNOWN; + int retry = 3; + + while (retry--) + { + lcd_read_display_id(LCD_MPUIFACE_SERIAL, &lcd_id[0]); + + if (lcd_id[1] == 0x38) { + if (lcd_id[2] == 0xb3) type = LCD_TYPE_B3; + else if (lcd_id[2] == 0xc4) type = LCD_TYPE_C4; + else if (lcd_id[2] == 0xd5) type = LCD_TYPE_D5; + else if (lcd_id[2] == 0xe6) type = LCD_TYPE_E6; + } + + if (type != LCD_TYPE_UNKNOWN) + return &lcd_info_list[type]; + } + +#ifdef BOOTLOADER + while (1) + { + uint16_t fatal[] = { 3000,500,500, 0 }; + piezo_seq(fatal); + } +#else + // TODO: What we do? + return lcd_info_list; +#endif +} diff --git a/firmware/target/arm/s5l8702/ipodnano4g/lcd-target.h b/firmware/target/arm/s5l8702/ipodnano4g/lcd-target.h new file mode 100644 index 0000000000..d5ec89ceca --- /dev/null +++ b/firmware/target/arm/s5l8702/ipodnano4g/lcd-target.h @@ -0,0 +1,34 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: lcd-nano2g.c 28868 2010-12-21 06:59:17Z Buschel $ + * + * Copyright (C) 2009 by Dave Chapman + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef __LCD_TARGET_H__ +#define __LCD_TARGET_H__ + +// #include "config.h" + +/* define this to add support for LCDs with 16-bit command set */ +// #define S5L_LCD_WITH_CMDSET16 + +/* define this to include support for LCD read ID command */ +#define S5L_LCD_WITH_READID + +// struct lcd_info_rec* lcd_target_get_info(void); + +#endif /* __LCD_TARGET_H__ */ diff --git a/firmware/target/arm/s5l8702/ipodnano4g/nand-nano4g.c b/firmware/target/arm/s5l8702/ipodnano4g/nand-nano4g.c new file mode 100644 index 0000000000..93c88583a9 --- /dev/null +++ b/firmware/target/arm/s5l8702/ipodnano4g/nand-nano4g.c @@ -0,0 +1,63 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2009 by Michael Sparmann + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "mv.h" + +int nand_init(void) +{ + // TODO + return 0; +} + +int nand_read_sectors(IF_MD(int drive,) sector_t start, int incount, + void* inbuf) +{ + // TODO +#ifdef HAVE_MULTIDRIVE + (void) drive; +#endif + (void) start; + (void) incount; + (void) inbuf; + return 0; +} + +int nand_write_sectors(IF_MD(int drive,) sector_t start, int count, + const void* outbuf) +{ + // TODO +#ifdef HAVE_MULTIDRIVE + (void) drive; +#endif + (void) start; + (void) count; + (void) outbuf; + return 0; +} + +int nand_event(long id, intptr_t data) +{ + // TODO + (void) id; + (void) data; + + return 0; +} diff --git a/firmware/target/arm/s5l8702/ipodnano4g/piezo-nano4g.c b/firmware/target/arm/s5l8702/ipodnano4g/piezo-nano4g.c new file mode 100644 index 0000000000..c299ea3eb6 --- /dev/null +++ b/firmware/target/arm/s5l8702/ipodnano4g/piezo-nano4g.c @@ -0,0 +1,133 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2006-2007 Robert Keevil + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "system.h" +#include "kernel.h" +#include "piezo.h" + +static unsigned int duration; +static bool beeping; + +void INT_TIMERA(void) +{ + /* clear interrupt */ + TACON = TACON; + if (!(--duration)) + piezo_stop(); +} + +static void piezo_gpio_enable(bool enable) +{ + PCON1 = (PCON1 & ~0xff) | (enable ? 0x53 : 0xee); +} + +static void piezo_start(unsigned short cycles, unsigned short periods) +{ +#ifndef SIMULATOR + duration = periods; + beeping = 1; + /* select TA_OUT function on GPIO ports */ + piezo_gpio_enable(true); +// /* configure timer for 100 kHz (12 MHz / 4 / 30) */ + /* configure timer for 100 kHz (24 MHz / 4 / 60) */ + TACMD = (1 << 1); /* TA_CLR */ +// TAPRE = 30 - 1; /* prescaler */ + TAPRE = 60 - 1; /* prescaler */ + TACON = (1 << 13) | /* TA_INT1_EN */ + (0 << 12) | /* TA_INT0_EN */ + (0 << 11) | /* TA_START */ + (1 << 8) | /* TA_CS = ECLK / 4 */ +// (1 << 6) | /* select ECLK (12 MHz) */ + (1 << 6) | /* select ECLK (24 MHz) */ + (1 << 4); /* TA_MODE_SEL = PWM mode */ + TADATA0 = cycles; /* set interval period */ + TADATA1 = cycles << 1; /* set interval period */ + TACMD = (1 << 0); /* TA_EN */ +#endif +} + +void piezo_stop(void) +{ +#ifndef SIMULATOR + beeping = 0; + TACMD = (1 << 1); /* TA_CLR */ + /* configure GPIO for the lowest power consumption */ + piezo_gpio_enable(false); +#endif +} + +void piezo_clear(void) +{ + piezo_stop(); +} + +bool piezo_busy(void) +{ + return beeping; +} + +void piezo_init(void) +{ + piezo_stop(); +} + +void piezo_button_beep(bool beep, bool force) +{ + if (force) + while (beeping) + yield(); + + if (!beeping) + { + if (beep) + piezo_start(22, 457); + else + piezo_start(40, 4); + } +} + +#ifdef BOOTLOADER +void piezo_tone(uint32_t period /*uS*/, int32_t duration /*ms*/) +{ + int32_t stop = USEC_TIMER + duration*1000; + uint32_t level = 0; + + piezo_gpio_enable(true); + while ((int32_t)USEC_TIMER - stop < 0) + { + level ^= 1; + GPIOCMD = 0x1000e | level; + udelay(period >> 1); + } + piezo_gpio_enable(false); +} + +void piezo_seq(uint16_t *seq) +{ + uint16_t period; + + while ((period = *seq++) != 0) + { + piezo_tone(period, *seq++); + udelay(*seq++ * 1000); + } +} +#endif diff --git a/firmware/target/arm/s5l8702/ipodnano4g/piezo.h b/firmware/target/arm/s5l8702/ipodnano4g/piezo.h new file mode 100644 index 0000000000..ff6d562e0b --- /dev/null +++ b/firmware/target/arm/s5l8702/ipodnano4g/piezo.h @@ -0,0 +1,37 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2006-2007 Robert Keevil + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef __PIEZO_H__ +#define __PIEZO_H__ +#include + +void piezo_init(void); +void piezo_stop(void); +void piezo_clear(void); +bool piezo_busy(void); +void piezo_button_beep(bool beep, bool force); + +#ifdef BOOTLOADER +#include +void piezo_tone(uint32_t period, int32_t duration); +void piezo_seq(uint16_t *seq); +#endif + +#endif /* __PIEZO_H__ */ diff --git a/firmware/target/arm/s5l8702/ipodnano4g/pmu-nano4g.c b/firmware/target/arm/s5l8702/ipodnano4g/pmu-nano4g.c new file mode 100644 index 0000000000..42ec168cb1 --- /dev/null +++ b/firmware/target/arm/s5l8702/ipodnano4g/pmu-nano4g.c @@ -0,0 +1,388 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: pmu-nano2g.c 27752 2010-08-08 10:49:32Z bertrik $ + * + * Copyright © 2008 Rafaël Carré + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "config.h" +#include "kernel.h" +#include "thread.h" + +#include "pmu-target.h" +#include "adc-target.h" +#include "i2c-s5l8702.h" +#include "gpio-s5l8702.h" + + +int pmu_read_multiple(int address, int count, unsigned char* buffer) +{ + return i2c_read(0, 0xe6, address, count, buffer); +} + +int pmu_write_multiple(int address, int count, unsigned char* buffer) +{ + return i2c_write(0, 0xe6, address, count, buffer); +} + +unsigned char pmu_read(int address) +{ + unsigned char tmp; + pmu_read_multiple(address, 1, &tmp); + return tmp; +} + +int pmu_write(int address, unsigned char val) +{ + return pmu_write_multiple(address, 1, &val); +} + +#if 0 +void pmu_ldo_on_in_standby(unsigned int ldo, int onoff) +{ + if (ldo < 4) + { + unsigned char newval = pmu_read(0x3B) & ~(1 << (2 * ldo)); + if (onoff) newval |= 1 << (2 * ldo); + pmu_write(0x3B, newval); + } + else if (ldo < 8) + { + unsigned char newval = pmu_read(0x3C) & ~(1 << (2 * (ldo - 4))); + if (onoff) newval |= 1 << (2 * (ldo - 4)); + pmu_write(0x3C, newval); + } +} + +void pmu_ldo_set_voltage(unsigned int ldo, unsigned char voltage) +{ + if (ldo > 6) return; + pmu_write(0x2d + (ldo << 1), voltage); +} + +void pmu_hdd_power(bool on) +{ + pmu_write(0x1b, on ? 1 : 0); +} + +void pmu_ldo_power_on(unsigned int ldo) +{ + if (ldo > 6) return; + pmu_write(0x2e + (ldo << 1), 1); +} + +void pmu_ldo_power_off(unsigned int ldo) +{ + if (ldo > 6) return; + pmu_write(0x2e + (ldo << 1), 0); +} +#endif + +void pmu_set_wake_condition(unsigned char condition) +{ + // TODO + (void) condition; +} + +void pmu_enter_standby(void) +{ + // TODO +} + +#ifdef HAVE_ADJUSTABLE_CPU_FREQ +void pmu_set_cpu_voltage(bool high) +{ + // TODO + (void) high; +} +#endif + +#if (CONFIG_RTC == RTC_NANO4G) +void pmu_read_rtc(unsigned char* buffer) +{ + // TODO + (void) buffer; +} + +void pmu_write_rtc(unsigned char* buffer) +{ + // TODO + (void) buffer; +} +#endif + +void pmu_set_usblimit(bool fast_charge) +{ + // TODO + (void) fast_charge; +} + +/* + * ADC + */ +static struct mutex pmu_adc_mutex; + +/* converts raw value to millivolts */ +unsigned short pmu_adc_raw2mv( + const struct pmu_adc_channel *ch, unsigned short raw) +{ + // TODO + (void) ch; + (void) raw; + return 0; +} + +/* returns raw value */ +unsigned short pmu_read_adc(const struct pmu_adc_channel *ch) +{ + // TODO + int raw = 0; + mutex_lock(&pmu_adc_mutex); + (void) ch; + mutex_unlock(&pmu_adc_mutex); + return raw; +} + +/* + * eINT + */ +#define Q_EINT 0 + +static char pmu_thread_stack[DEFAULT_STACK_SIZE/2]; +static struct event_queue pmu_queue; +static unsigned char ints_msk[3]; + +static void pmu_eint_isr(struct eic_handler*); + +static struct eic_handler pmu_eint = +{ + .gpio_n = GPIO_EINT_PMU, + .type = EIC_INTTYPE_LEVEL, + .level = EIC_INTLEVEL_LOW, + .isr = pmu_eint_isr, +}; + +static int pmu_input_holdswitch; + +int pmu_holdswitch_locked(void) +{ + return pmu_input_holdswitch; +} + +#ifdef IPOD_ACCESSORY_PROTOCOL +static int pmu_input_accessory; + +int pmu_accessory_present(void) +{ + return pmu_input_accessory; +} +#endif + +#if CONFIG_CHARGING +static int pmu_input_firewire; + +int pmu_firewire_present(void) +{ + return pmu_input_firewire; +} +#endif + +#if 1 // XXX: from usb-s5l8702.c +#include "usb.h" +static int usb_status = USB_EXTRACTED; + +int usb_detect(void) +{ + return usb_status; +} + +void usb_insert_int(void) +{ + usb_status = USB_INSERTED; +} + +void usb_remove_int(void) +{ + usb_status = USB_EXTRACTED; +} +#endif + +static void pmu_read_inputs(void) +{ +#if CONFIG_CHARGING + unsigned char status[3]; +#else + unsigned char status[2]; +#endif + + pmu_read_multiple(D1759_REG_STATUSA, sizeof(status), status); + + if (status[0] & D1759_STATUSA_VBUS) + usb_insert_int(); + else + usb_remove_int(); + +#ifdef IPOD_ACCESSORY_PROTOCOL + pmu_input_accessory = !!(status[0] & D1759_STATUSA_INPUT1); +#endif + pmu_input_holdswitch = !(status[1] & D1759_STATUSB_INPUT2); +#if CONFIG_CHARGING + pmu_input_firewire = !!(status[2] & D1759_STATUSC_VADAPTOR); +#endif +} + +static void pmu_eint_isr(struct eic_handler *h) +{ + eint_unregister(h); + queue_post(&pmu_queue, Q_EINT, 0); +} + +static void NORETURN_ATTR pmu_thread(void) +{ + struct queue_event ev; + + while (true) + { + queue_wait_w_tmo(&pmu_queue, &ev, TIMEOUT_BLOCK); + switch (ev.id) + { + case Q_EINT: + /* clear all PMU interrupts, this will also raise + (disable) the PMU IRQ pin */ +#if CONFIG_CHARGING + pmu_write_multiple(D1759_REG_EVENTA, 3, "\xFF\xFF\xFF"); +#else + pmu_write_multiple(D1759_REG_EVENTA, 2, "\xFF\xFF"); +#endif + + /* get actual values */ + pmu_read_inputs(); + + eint_register(&pmu_eint); + break; + + case SYS_TIMEOUT: + break; + } + } +} + +/* main init */ +void pmu_init(void) +{ + mutex_init(&pmu_adc_mutex); + queue_init(&pmu_queue, false); + + create_thread(pmu_thread, + pmu_thread_stack, sizeof(pmu_thread_stack), 0, + "PMU" IF_PRIO(, PRIORITY_SYSTEM) IF_COP(, CPU)); + + /* configure PMU interrutps */ + ints_msk[0] = 0xff; + ints_msk[1] = 0xff; + ints_msk[2] = 0xff; + + ints_msk[0] &= ~D1759_IRQMASKA_VBUS; /* USB */ +#ifdef IPOD_ACCESSORY_PROTOCOL + ints_msk[0] &= ~D1759_IRQMASKA_INPUT1; /* Accessory */ +#endif + ints_msk[1] &= ~D1759_IRQMASKB_INPUT2; /* Holdswitch */ +#if CONFIG_CHARGING + ints_msk[2] &= ~D1759_IRQMASKC_VADAPTOR; /* FireWire */ +#endif + + pmu_write_multiple(D1759_REG_IRQMASKA, 3, ints_msk); + + /* clear all interrupts */ + pmu_write_multiple(D1759_REG_EVENTA, 3, "\xFF\xFF\xFF"); + + /* get initial values */ + pmu_read_inputs(); + + eint_register(&pmu_eint); +} + + +/* + * preinit + */ +int pmu_rd_multiple(int address, int count, unsigned char* buffer) +{ + return i2c_rd(0, 0xe6, address, count, buffer); +} + +int pmu_wr_multiple(int address, int count, unsigned char* buffer) +{ + return i2c_wr(0, 0xe6, address, count, buffer); +} + +unsigned char pmu_rd(int address) +{ + unsigned char val; + pmu_rd_multiple(address, 1, &val); + return val; +} + +int pmu_wr(int address, unsigned char val) +{ + return pmu_wr_multiple(address, 1, &val); +} + +void pmu_preinit(void) +{ + pmu_wr(0x14, 0x13); + pmu_wr(0x15, 0x0d); + pmu_wr(0xb, 0x22); + if (pmu_rd(0x7f) & 1) + pmu_wr(0xd, (pmu_rd(0xd) & 0xdf)); +// if (unknown_boot_config & 1) // XXX: could it be disabling some LDO??? remember that in this type of PMU the LDO enable bits are +// pmu_wr(0xd, (pmu_rd(0xd) & 0xdf)); // located in other registers different from the voltage configuration??? + + // TBC: LDOs ??? + pmu_wr(0x1f, 0x14); + pmu_wr(0x1a, 0xb2); // XXX: 0xA & 0x12, maybe it's an option to always ON, or ON in stby or something like that, could it be the ARM7 ??? + pmu_wr(0x1a, 0xb2); // XXX: repeat, posibly a typo ??? ??? ??? + pmu_wr(0x19, 0x14); // XXX: TBC: NAND (by similarity with nano3g) + pmu_wr(0x21, 0x6); + pmu_wr(0x1d, 0x12); + pmu_wr(0x10, (pmu_rd(0x10) & 0x7f) | 0x60); + + pmu_wr(0x44, 0x72); // TBC: 0x40+ seems related to ADC + pmu_wr(0x40, pmu_rd(0x40) | 0x40); + + pmu_wr(0x33, (pmu_rd(0x33) & 0x3) | 0x50); + pmu_wr(0x34, (pmu_rd(0x34) & 0x80) | 0x54); // XXX: see DA9030 page 110 charge_control REG 0x28 + pmu_wr(0x22, 0); + + /* configure and clear interrupts */ + pmu_wr_multiple(D1759_REG_IRQMASKA, 3, "\x50\xFE\x2B"); + pmu_wr_multiple(D1759_REG_EVENTA, 3, "\xFF\xFF\xFF"); + + pmu_wr(D1759_REG_LEDOUT, 0x64); /* set backlight brightness to 40% */ + pmu_wr(D1759_REG_LEDCTL, + pmu_rd(D1759_REG_LEDCTL) | D1759_LEDCTL_ENABLE); /* backlight on */ + + pmu_wr(0xa, 0x70); + pmu_wr(0x13, 0x02); +} + +#ifdef BOOTLOADER +bool pmu_is_hibernated(void) +{ + return !!(pmu_rd(D1759_REG_EVENTB) & D1759_EVENTB_WARMBOOT); +} +#endif diff --git a/firmware/target/arm/s5l8702/ipodnano4g/pmu-target.h b/firmware/target/arm/s5l8702/ipodnano4g/pmu-target.h new file mode 100644 index 0000000000..578038ac52 --- /dev/null +++ b/firmware/target/arm/s5l8702/ipodnano4g/pmu-target.h @@ -0,0 +1,161 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: pmu-target.h 24721 2010-02-17 15:54:48Z theseven $ + * + * Copyright © 2009 Michael Sparmann + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef __PMU_TARGET_H__ +#define __PMU_TARGET_H__ + +#include +#include +#include "config.h" + + +/* undocummented PMU registers */ +enum d1759_regs { + D1759_REG_EVENTA = 0x01, + D1759_REG_EVENTB = 0x02, + D1759_REG_EVENTC = 0x03, + D1759_REG_STATUSA = 0x04, + D1759_REG_STATUSB = 0x05, + D1759_REG_STATUSC = 0x06, + D1759_REG_IRQMASKA = 0x07, + D1759_REG_IRQMASKB = 0x08, + D1759_REG_IRQMASKC = 0x09, +// D1759_REG_SYSCTRLA = 0x0a, +// D1759_REG_SYSCTRLB = 0x0b, + D1759_REG_LEDOUT = 0x30, + D1759_REG_LEDCTL = 0x31, +}; + +#if 1 +enum d1759_reg_eventa { + D1759_EVENTA_VBUS = 0x08, /* USB: 0 -> not present */ + D1759_EVENTA_INPUT1 = 0x20, /* accessory: 0 -> not present */ + D1759_EVENTA_UNK6 = 0x40, // ??? +}; +enum d1759_reg_eventb { + D1759_EVENTB_INPUT2 = 0x01, /* hold switch: 0 -> locked */ + D1759_EVENTB_WARMBOOT = 0x80, /* TBC */ +}; +enum d1759_reg_eventc { + D1759_EVENTC_VADAPTOR = 0x08, /* FireWire: 0 -> not present */ +}; + +enum d1759_reg_statusa { + D1759_STATUSA_VBUS = 0x08, + D1759_STATUSA_INPUT1 = 0x20, +}; +enum d1759_reg_statusb { + D1759_STATUSB_INPUT2 = 0x01, + D1759_STATUSB_WARMBOOT = 0x80, +}; +enum d1759_reg_statusc { + D1759_STATUSC_VADAPTOR = 0x08, +}; + +enum d1759_reg_irqmaska { + D1759_IRQMASKA_VBUS = 0x08, + D1759_IRQMASKA_INPUT1 = 0x20, +}; +enum d1759_reg_irqmaskb { + D1759_IRQMASKB_INPUT2 = 0x01, + D1759_IRQMASKB_WARMBOOT = 0x80, +}; +enum d1759_reg_irqmaskc { + D1759_IRQMASKC_VADAPTOR = 0x08, +}; +#else // TODO? +/* PMU interrupts */ +#define D1759_EVENTA_VBUS (1<<3) /* USB: 0 -> not present */ +#define D1759_EVENTA_INPUT1 (1<<5) /* accessory: 0 -> not present */ +#define D1759_EVENTA_UNK6 (1<<6) // ??? + +#define D1759_EVENTB_INPUT2 (1<<0) /* hold switch: 0 -> locked */ +#define D1759_EVENTB_WARMBOOT (1<<7) /* TBC */ + +#define D1759_EVENTC_VADAPTOR (1<<3) /* FireWire: 0 -> not present */ +#endif + +enum d1759_reg_ledctl { + D1759_LEDCTL_ENABLE = 0x01, +}; + + +/* GPIO for external PMU interrupt */ +// #define GPIO_EINT_PMU 0x7b // TODO: I think it is not this one, or it does not work well, also this GPIO does not exist in s5l8720 + +// #define GPIO_EINT_PMU 5 // 0.5 +// #define GPIO_EINT_PMU 14 // 1.6 +#define GPIO_EINT_PMU 46 // 5.6 +// #define GPIO_EINT_PMU 76 // 9.4 +// #define GPIO_EINT_PMU 91 // B.3 +// #define GPIO_EINT_PMU 97 // C.1 +// #define GPIO_EINT_PMU 98 // C.2 + + +struct pmu_adc_channel +{ + const char *name; + // TODO +}; + +void pmu_preinit(void); +void pmu_init(void); +unsigned char pmu_read(int address); +int pmu_write(int address, unsigned char val); +int pmu_read_multiple(int address, int count, unsigned char* buffer); +int pmu_write_multiple(int address, int count, unsigned char* buffer); +#ifdef BOOTLOADER +unsigned char pmu_rd(int address); +int pmu_wr(int address, unsigned char val); +int pmu_rd_multiple(int address, int count, unsigned char* buffer); +int pmu_wr_multiple(int address, int count, unsigned char* buffer); +bool pmu_is_hibernated(void); +#endif + +// void pmu_ldo_on_in_standby(unsigned int ldo, int onoff); +// void pmu_ldo_set_voltage(unsigned int ldo, unsigned char voltage); +// void pmu_ldo_power_on(unsigned int ldo); +// void pmu_ldo_power_off(unsigned int ldo); +void pmu_set_wake_condition(unsigned char condition); +void pmu_enter_standby(void); +// void pmu_nand_power(bool on); +#ifdef HAVE_ADJUSTABLE_CPU_FREQ +void pmu_set_cpu_voltage(bool high); +#endif +#if (CONFIG_RTC == RTC_NANO3G) +void pmu_read_rtc(unsigned char* buffer); +void pmu_write_rtc(unsigned char* buffer); +#endif +void pmu_set_usblimit(bool fast_charge); + +unsigned short pmu_read_adc(const struct pmu_adc_channel *ch); +unsigned short pmu_adc_raw2mv( + const struct pmu_adc_channel *ch, unsigned short raw); + +int pmu_holdswitch_locked(void); +#if CONFIG_CHARGING +int pmu_firewire_present(void); +#endif +#ifdef IPOD_ACCESSORY_PROTOCOL +int pmu_accessory_present(void); +#endif + +#endif /* __PMU_TARGET_H__ */ diff --git a/firmware/target/arm/s5l8702/ipodnano4g/power-nano4g.c b/firmware/target/arm/s5l8702/ipodnano4g/power-nano4g.c new file mode 100644 index 0000000000..ec42763a0b --- /dev/null +++ b/firmware/target/arm/s5l8702/ipodnano4g/power-nano4g.c @@ -0,0 +1,70 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: power-nano2g.c 28190 2010-10-01 18:09:10Z Buschel $ + * + * Copyright © 2009 Bertrik Sikken + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include +#include "config.h" +#include "inttypes.h" +#include "s5l87xx.h" +#include "power.h" +#include "panic.h" +#include "pmu-target.h" +#include "usb_core.h" /* for usb_charging_maxcurrent_change */ + +void power_init(void) +{ + pmu_init(); + pmu_set_usblimit(false); /* limit to 100mA */ +} + +void power_off(void) +{ +// /* USB inserted or EXTON1 */ +// pmu_set_wake_condition(/*TODO*/); + pmu_enter_standby(); + while(1); +} + +#if CONFIG_CHARGING + +#ifdef HAVE_USB_CHARGING_ENABLE +void usb_charging_maxcurrent_change(int maxcurrent) +{ +// bool suspend_charging = (maxcurrent < 100); + bool fast_charging = (maxcurrent >= 500); + pmu_set_usblimit(fast_charging); +} +#endif + +unsigned int power_input_status(void) +{ + unsigned int status = POWER_INPUT_NONE; + if (usb_detect() == USB_INSERTED) + status |= POWER_INPUT_USB_CHARGER; + if (pmu_firewire_present()) + status |= POWER_INPUT_MAIN_CHARGER; + return status; +} + +bool charging_state(void) +{ + // TODO + return false; +} +#endif /* CONFIG_CHARGING */ diff --git a/firmware/target/arm/s5l8702/ipodnano4g/powermgmt-nano4g.c b/firmware/target/arm/s5l8702/ipodnano4g/powermgmt-nano4g.c new file mode 100644 index 0000000000..7cafe4fe66 --- /dev/null +++ b/firmware/target/arm/s5l8702/ipodnano4g/powermgmt-nano4g.c @@ -0,0 +1,81 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: powermgmt-nano2g.c 28159 2010-09-24 22:42:06Z Buschel $ + * + * Copyright © 2008 Rafaël Carré + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "config.h" +#include "powermgmt.h" +#include "pmu-target.h" +#include "power.h" +#include "audiohw.h" +#include "adc-target.h" + +const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = +{ + 3500 +}; + +const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] = +{ + 3300 +}; + +/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */ +const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] = +{ + { 3500, 3670, 3720, 3750, 3770, 3800, 3860, 3920, 3980, 4070, 4170 } +}; + +#if CONFIG_CHARGING +/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */ +const unsigned short percent_to_volt_charge[11] = +{ + 3700, 3820, 3900, 3950, 3990, 4030, 4070, 4120, 4170, 4190, 4200 +}; +#endif /* CONFIG_CHARGING */ + +/* Returns battery voltage from ADC [millivolts] */ +int _battery_voltage(void) +{ + return adc_read_battery_voltage(); +} + +#ifdef HAVE_ACCESSORY_SUPPLY +void accessory_supply_set(bool enable) +{ + if (enable) + { + /* Accessory voltage supply on */ +// pmu_ldo_power_on(6); + } + else + { + /* Accessory voltage supply off */ +// pmu_ldo_power_off(6); + } +} +#endif + +#ifdef HAVE_LINEOUT_POWEROFF +void lineout_set(bool enable) +{ + /* Call audio hardware driver implementation */ + audiohw_enable_lineout(enable); +} +#endif diff --git a/firmware/target/arm/s5l8702/ipodnano4g/rtc-nano4g.c b/firmware/target/arm/s5l8702/ipodnano4g/rtc-nano4g.c new file mode 100644 index 0000000000..615ac34b8a --- /dev/null +++ b/firmware/target/arm/s5l8702/ipodnano4g/rtc-nano4g.c @@ -0,0 +1,73 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: rtc-nano2g.c 23114 2009-10-11 18:20:56Z theseven $ + * + * Copyright (C) 2002 by Linus Nielsen Feltzing, Uwe Freese, Laurent Baum + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "config.h" +#include "rtc.h" +#include "kernel.h" +#include "system.h" +#include "pmu-target.h" +#include "timefuncs.h" + + +void rtc_init(void) +{ +} + +int rtc_read_datetime(struct tm *tm) +{ + unsigned int i; + unsigned char buf[7]; + + pmu_read_rtc(buf); + + for (i = 0; i < sizeof(buf); i++) + buf[i] = BCD2DEC(buf[i]); + + tm->tm_sec = buf[0]; + tm->tm_min = buf[1]; + tm->tm_hour = buf[2]; + tm->tm_mday = buf[4]; + tm->tm_mon = buf[5] - 1; + tm->tm_year = buf[6] + 100; + tm->tm_yday = 0; /* Not implemented for now */ + + set_day_of_week(tm); + return 0; +} + +int rtc_write_datetime(const struct tm *tm) +{ + unsigned int i; + unsigned char buf[7]; + + buf[0] = tm->tm_sec; + buf[1] = tm->tm_min; + buf[2] = tm->tm_hour; + buf[3] = tm->tm_wday; + buf[4] = tm->tm_mday; + buf[5] = tm->tm_mon + 1; + buf[6] = tm->tm_year - 100; + + for (i = 0; i < sizeof(buf); i++) + buf[i] = DEC2BCD(buf[i]); + + pmu_write_rtc(buf); + return 0; +} diff --git a/firmware/target/arm/s5l8702/ipodnano4g/serial-nano4g.c b/firmware/target/arm/s5l8702/ipodnano4g/serial-nano4g.c new file mode 100644 index 0000000000..7e0bffa201 --- /dev/null +++ b/firmware/target/arm/s5l8702/ipodnano4g/serial-nano4g.c @@ -0,0 +1,249 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2014 by Cástor Muñoz + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include +#include + +#include "config.h" +#include "cpu.h" +#include "system.h" +#include "serial.h" + +#include "s5l87x.h" +#include "uc87xx.h" + +/* Define LOGF_ENABLE to enable logf output in this file */ +#define LOGF_ENABLE +#include "logf.h" + + +/* shall include serial HW configuracion for specific target */ +#define IPOD6G_UART_CLK_HZ 12000000 /* external OSC0 ??? */ + +/* This values below are valid with a UCLK of 12MHz */ +#define BRDATA_9600 (77) /* 9615 */ +#define BRDATA_19200 (38) /* 19231 */ +#define BRDATA_28800 (25) /* 28846 */ +#define BRDATA_38400 (19 | (0xc330c << 8)) /* 38305 */ +#define BRDATA_57600 (12) /* 57692 */ +#define BRDATA_115200 (6 | (0xffffff << 8)) /* 114286 */ + + +extern const struct uartc s5l8702_uartc; +#ifdef IPOD_ACCESSORY_PROTOCOL +static void iap_rx_isr(int, char*, char*, uint32_t); +#endif + +struct uartc_port ser_port IDATA_ATTR = +{ + /* location */ + .uartc = &s5l8702_uartc, + .id = 0, + + /* configuration */ + .rx_trg = UFCON_RX_FIFO_TRG_4, + .tx_trg = UFCON_TX_FIFO_TRG_EMPTY, + .clksel = UCON_CLKSEL_ECLK, + .clkhz = IPOD6G_UART_CLK_HZ, + + /* interrupt callbacks */ +#ifdef IPOD_ACCESSORY_PROTOCOL + .rx_cb = iap_rx_isr, +#else + .rx_cb = NULL, +#endif + .tx_cb = NULL, /* polling */ +}; + +/* + * serial driver API + */ +int tx_rdy(void) +{ + return uartc_port_tx_ready(&ser_port) ? 1 : 0; +} + +void tx_writec(unsigned char c) +{ + uartc_port_tx_byte(&ser_port, c); +} + +#ifndef IPOD_ACCESSORY_PROTOCOL +void serial_setup(void) +{ + uartc_port_open(&ser_port); + + /* set a default configuration, Tx and Rx modes are + disabled when the port is initialized */ + uartc_port_config(&ser_port, ULCON_DATA_BITS_8, + ULCON_PARITY_NONE, ULCON_STOP_BITS_1); + uartc_port_set_bitrate_raw(&ser_port, BRDATA_115200); + + /* enable Tx interrupt request or POLLING mode */ + uartc_port_set_tx_mode(&ser_port, UCON_MODE_INTREQ); + + logf("[%lu] "MODEL_NAME" port %d ready!", USEC_TIMER, ser_port.id); +} + + +#else /* IPOD_ACCESSORY_PROTOCOL */ +#include "kernel.h" +#include "pmu-target.h" +#include "iap.h" + +static enum { + ABR_STATUS_LAUNCHED, /* ST_SYNC */ + ABR_STATUS_SYNCING, /* ST_SOF */ + ABR_STATUS_DONE +} abr_status; + +static int bitrate = 0; +static bool acc_plugged = false; + +static void serial_acc_tick(void) +{ + bool plugged = pmu_accessory_present(); + if (acc_plugged != plugged) + { + acc_plugged = plugged; + if (acc_plugged) + { + uartc_open(ser_port.uartc); + uartc_port_open(&ser_port); + /* set a default configuration, Tx and Rx modes are + disabled when the port is initialized */ + uartc_port_config(&ser_port, ULCON_DATA_BITS_8, + ULCON_PARITY_NONE, ULCON_STOP_BITS_1); + uartc_port_set_tx_mode(&ser_port, UCON_MODE_INTREQ); + serial_bitrate(bitrate); + } + else + { + uartc_port_close(&ser_port); + uartc_close(ser_port.uartc); + } + } +} + +void serial_setup(void) +{ + uartc_close(ser_port.uartc); + tick_add_task(serial_acc_tick); +} + +void serial_bitrate(int rate) +{ + bitrate = rate; + if (!acc_plugged) + return; + + logf("[%lu] serial_bitrate(%d)", USEC_TIMER, rate); + + if (rate == 0) { + /* Using auto-bitrate (ABR) to detect accessory Tx speed: + * + * + Here: + * - Disable Rx logic to clean the FIFO and the shift + * register, thus no Rx data interrupts are generated. + * - Launch ABR and wait for a low pulse in Rx line. + * + * + In ISR, when a low pulse is detected (ideally it is the + * start bit of 0xff): + * - Calculate and configure detected speed. + * - Enable Rx to verify that the next received data frame + * is 0x55 or 0xff: + * - If so, it's assumed bit rate is correctly detected, + * it will not be modified until speed is changed using + * RB options menu. + * - If not, reset iAP state machine and launch a new ABR. + */ + uartc_port_set_rx_mode(&ser_port, UCON_MODE_DISABLED); + uartc_port_abr_start(&ser_port); + abr_status = ABR_STATUS_LAUNCHED; + } + else { + uint32_t brdata; + if (rate == 57600) brdata = BRDATA_57600; + else if (rate == 38400) brdata = BRDATA_38400; + else if (rate == 19200) brdata = BRDATA_19200; + else brdata = BRDATA_9600; + uartc_port_abr_stop(&ser_port); /* abort ABR if already launched */ + uartc_port_set_bitrate_raw(&ser_port, brdata); + uartc_port_set_rx_mode(&ser_port, UCON_MODE_INTREQ); + abr_status = ABR_STATUS_DONE; + } +} + +static void iap_rx_isr(int len, char *data, char *err, uint32_t abr_cnt) +{ + /* ignore Rx errors, upper layer will discard bad packets */ + (void) err; + + static int sync_retry; + + if (abr_status == ABR_STATUS_LAUNCHED) { + /* autobauding */ + if (abr_cnt) { + #define BR2CNT(s) (IPOD6G_UART_CLK_HZ / (unsigned)(s)) + if (abr_cnt < BR2CNT(57600*1.1) || abr_cnt > BR2CNT(9600*0.9)) { + /* detected speed out of range, relaunch ABR */ + uartc_port_abr_start(&ser_port); + return; + } + /* valid speed detected, select it */ + uint32_t brdata; + if (abr_cnt < BR2CNT(48000)) brdata = BRDATA_57600; + else if (abr_cnt < BR2CNT(33600)) brdata = BRDATA_38400; + else if (abr_cnt < BR2CNT(24000)) brdata = BRDATA_28800; + else if (abr_cnt < BR2CNT(14400)) brdata = BRDATA_19200; + else brdata = BRDATA_9600; + + /* set detected speed */ + uartc_port_set_bitrate_raw(&ser_port, brdata); + uartc_port_set_rx_mode(&ser_port, UCON_MODE_INTREQ); + + /* enter SOF state */ + iap_getc(0xff); + + abr_status = ABR_STATUS_SYNCING; + sync_retry = 2; /* we are expecting [0xff] 0x55 */ + } + } + + /* process received data */ + while (len--) + { + bool sync_done = !iap_getc(*data++); + + if (abr_status == ABR_STATUS_SYNCING) + { + if (sync_done) { + abr_status = ABR_STATUS_DONE; + } + else if (--sync_retry == 0) { + /* invalid speed detected, relaunch ABR + discarding remaining data (if any) */ + serial_bitrate(0); + break; + } + } + } +} +#endif /* IPOD_ACCESSORY_PROTOCOL */ diff --git a/tools/configure b/tools/configure index aee55b023d..f5614d7ff9 100755 --- a/tools/configure +++ b/tools/configure @@ -1679,49 +1679,49 @@ cat <