New port: iPod Nano 3G

Currently, only a bootloader can be built successfully. The development bootloader is functional, it enables further progress on the port.

This is a part of the large iPod Nano 3G and iPod Nano 4G support patch.

Credit: Cástor Muñoz <cmvidal@gmail.com>
Change-Id: Idf85e42334b0e0ae36f9ed273e2940d5d7736e34
This commit is contained in:
Vencislav Atanasov 2024-12-16 16:24:30 +02:00 committed by Solomon Peachy
parent 96615af033
commit d6cd237f80
24 changed files with 2458 additions and 68 deletions

View file

@ -696,7 +696,8 @@ void main(void)
printf("lcd type: %d", lcd_type); printf("lcd type: %d", lcd_type);
#ifdef S5L_LCD_WITH_READID #ifdef S5L_LCD_WITH_READID
extern unsigned char lcd_id[4]; extern unsigned char lcd_id[4];
printf("lcd id: 0x%x", *((uint32_t*)&lcd_id[0])); uint32_t* lcd_id_32 = (uint32_t *)lcd_id;
printf("lcd id: 0x%x", *lcd_id_32);
#endif #endif
#ifdef IPOD_NANO4G #ifdef IPOD_NANO4G
printf("boot cfg: 0x%x", pmu_read(0x7f)); printf("boot cfg: 0x%x", pmu_read(0x7f));

View file

@ -1604,6 +1604,27 @@ target/arm/s5l8700/ipodnano2g/piezo-nano2g.c
#endif #endif
#endif /* IPOD_NANO2G */ #endif /* IPOD_NANO2G */
#ifdef IPOD_NANO3G
target/arm/s5l8702/ipodnano3g/lcd-nano3g.c
target/arm/s5l8702/ipodnano3g/backlight-nano3g.c
target/arm/s5l8702/ipodnano3g/piezo-nano3g.c
target/arm/s5l8702/ipodnano3g/pmu-nano3g.c
target/arm/s5l8702/ipodnano3g/adc-nano3g.c
target/arm/s5l8702/ipodnano3g/powermgmt-nano3g.c
target/arm/s5l8702/ipodnano3g/power-nano3g.c
target/arm/s5l8702/ipodnano3g/nand-nano3g.c
#if (CONFIG_RTC == RTC_NANO3G)
target/arm/s5l8702/ipodnano3g/rtc-nano3g.c // TODO: -> drivers/rtc/rtc_xxx.c ???
#endif
#ifdef HAVE_SERIAL
target/arm/s5l8702/ipodnano3g/serial-nano3g.c
#endif
#ifndef BOOTLOADER
target/arm/s5l8702/ipodnano3g/audio-nano3g.c
target/arm/s5l8702/ipodnano3g/cscodec-nano3g.c // TODO: -> wmcodec-nano3g.c
#endif
#endif /* IPOD_NANO3G */
#ifdef IPOD_6G #ifdef IPOD_6G
target/arm/s5l8702/ipod6g/lcd-6g.c target/arm/s5l8702/ipod6g/lcd-6g.c
target/arm/s5l8702/ipod6g/backlight-6g.c target/arm/s5l8702/ipod6g/backlight-6g.c

View file

@ -420,6 +420,8 @@ Lyre prototype 1 */
#include "config/ipod4g.h" #include "config/ipod4g.h"
#elif defined(IPOD_NANO2G) #elif defined(IPOD_NANO2G)
#include "config/ipodnano2g.h" #include "config/ipodnano2g.h"
#elif defined(IPOD_NANO3G)
#include "config/ipodnano3g.h"
#elif defined(IPOD_6G) #elif defined(IPOD_6G)
#include "config/ipod6g.h" #include "config/ipod6g.h"
#elif defined(GIGABEAT_F) #elif defined(GIGABEAT_F)

View file

@ -0,0 +1,272 @@
/*
* This config file is for iPod Nano 3rd Generation
*/
#define IPOD_ARCH 1
/* For Rolo and boot loader */
#define MODEL_NUMBER 117
#define MODEL_NAME "Apple iPod Nano 3G"
/* 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 320
#define LCD_HEIGHT 240
/* 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
// 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
#if 0
/* Define the type of audio codec */
#define HAVE_WM1870
#endif
// XXX: dummy for preliminary build, WRONG CODEC!!!
#define HAVE_CS42L55
#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 S5L8702
/* Define this to the CPU frequency */
#define CPU_FREQ 216000000
/* 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 0x1262
#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

View file

@ -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)
{
}

View file

@ -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 <stdbool.h>
#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

View file

@ -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 */

View file

@ -0,0 +1,68 @@
/***************************************************************************
* __________ __ ___.
* 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 <stdbool.h>
#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
// TODO: test
void backlight_hw_brightness(int brightness)
{
pmu_write(D1671_REG_LEDCTL,
(pmu_read(D1671_REG_LEDCTL) & ~D1671_LEDCTL_OUT_MASK) | (brightness>>1));
}
void backlight_hw_on(void)
{
#ifdef HAVE_LCD_SLEEP
if (!lcd_active())
lcd_awake();
#endif
pmu_write(D1671_REG_LEDCTL,
(pmu_read(D1671_REG_LEDCTL) | D1671_LEDCTL_ENABLE));
}
void backlight_hw_off(void)
{
pmu_write(D1671_REG_LEDCTL,
(pmu_read(D1671_REG_LEDCTL) & ~D1671_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();
}

View file

@ -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

View file

@ -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_ */

View file

@ -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)
{
// XXX: 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)
{
// XXX: not tested
if (state) PDAT(3) &= ~8;
else PDAT(3) |= 8;
}
void cscodec_clock(bool state)
{
// XXX: not tested
if (state) CLKCON3 &= ~0xffff;
else CLKCON3 |= 0x8000;
}

View file

@ -0,0 +1,419 @@
/***************************************************************************
* __________ __ ___.
* 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 <stdint.h>
#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
/* Supported LCD types */
enum {
LCD_TYPE_UNKNOWN = -1,
LCD_TYPE_38B3 = 0,
LCD_TYPE_38C4,
LCD_TYPE_38D5,
LCD_TYPE_38E6,
LCD_TYPE_58XX,
N_LCD_TYPES
};
#if defined(HAVE_LCD_SLEEP) || defined(HAVE_LCD_SHUTDOWN)
/* sleep sequences */
/* 0xb3, 0xe6 */
static const uint8_t lcd_sleep_seq_03[] =
{
CMD, 0x28, 0, /* Display Off */
CMD, 0x10, 0, /* Sleep In */
SLEEP, 5, /* 50 ms */
END
};
/* 0xc4 */
static const uint8_t lcd_sleep_seq_1[] =
{
CMD, 0x28, 0, /* Display Off */
CMD, 0x10, 0, /* Sleep In */
SLEEP, 12, /* 120 ms */
END
};
/* 0xd5 */
static const uint8_t lcd_sleep_seq_2[] =
{
CMD, 0x28, 0, /* Display Off */
CMD, 0x10, 0, /* Sleep In */
END
};
/* 0x58 */
static const uint8_t lcd_sleep_seq_4[] =
{
CMD, 0x10, 0, /* Sleep In */
END
};
// static const void* seq_sleep_by_type[] =
static void* seq_sleep_by_type[] =
{
[LCD_TYPE_38B3] = (void*) lcd_sleep_seq_03,
[LCD_TYPE_38C4] = (void*) lcd_sleep_seq_1,
[LCD_TYPE_38D5] = (void*) lcd_sleep_seq_2,
[LCD_TYPE_38E6] = (void*) lcd_sleep_seq_03,
[LCD_TYPE_58XX] = (void*) lcd_sleep_seq_4,
};
#endif /* HAVE_LCD_SLEEP || HAVE_LCD_SHUTDOWN */
#if defined(HAVE_LCD_SLEEP)
/* awake sequences */
/* 0xb3, 0xc4, 0xd5, 0xd6, 0x58 */
static const uint8_t lcd_awake_seq_01234[] =
{
CMD, 0x11, 0, /* Sleep Out */
SLEEP, 12, /* 120 ms */
CMD, 0x29, 0, /* Display On */
SLEEP, 1, /* 10 ms */
END
};
static void* seq_awake_by_type[] =
{
[LCD_TYPE_38B3] = (void*) lcd_awake_seq_01234,
[LCD_TYPE_38C4] = (void*) lcd_awake_seq_01234,
[LCD_TYPE_38D5] = (void*) lcd_awake_seq_01234,
[LCD_TYPE_38E6] = (void*) lcd_awake_seq_01234,
[LCD_TYPE_58XX] = (void*) lcd_awake_seq_01234,
};
#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[] =
{
CMD, 0xef, 1, 0x80,
/* 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,
/* 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 Access Control */
CMD, 0x13, 0, /* Normal Mode On */
/* Awake sequence */
CMD, 0x11, 0, /* Sleep Out */
SLEEP, 12, /* 120 ms */
CMD, 0x29, 0, /* Display On */
SLEEP, 1, /* 10 ms */
END
};
/* 0xc4 */
static const uint8_t lcd_init_seq_1[] =
{
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 */
/* Awake sequence */
CMD, 0x11, 0, /* Sleep Out */
SLEEP, 12, /* 120 ms */
CMD, 0x29, 0, /* Display On */
SLEEP, 1, /* 10 ms */
END
};
/* 0xd5 */
static const uint8_t lcd_init_seq_2[] =
{
CMD, 0xfe, 1, 0x00,
/* 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, 0x42, 0x57, 0x06, 0x00, 0x04, 0x43, 0x7b,
0x0f, 0x00, 0x00,
CMD, 0x3a, 1, 0x66, /* Pixel Format Set */
CMD, 0x36, 1, 0x60, /* Memory Access Control */
/* Awake sequence */
CMD, 0x11, 0, /* Sleep Out */
SLEEP, 12, /* 120 ms */
CMD, 0x29, 0, /* Display On */
SLEEP, 1, /* 10 ms */
END
};
/* 0xe6 */
static const uint8_t lcd_init_seq_3[] =
{
CMD, 0xef, 1, 0x80,
/* 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,
/* 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 */
/* Awake sequence */
CMD, 0x11, 0, /* Sleep Out */
SLEEP, 12, /* 120 ms */
CMD, 0x29, 0, /* Display On */
SLEEP, 1, /* 10 ms */
END
};
/* 0x58 */
static const uint8_t lcd_init_seq_4[] =
{
CMD, 0xe1, 3, 0x0f, 0x31, 0x04,
CMD, 0xe2, 5, 0x02, 0xa2, 0x08, 0x11, 0x01,
CMD, 0xe3, 2, 0x10, 0x88,
CMD, 0xe4, 2, 0x10, 0x88,
CMD, 0xe5, 2, 0x00, 0x88,
CMD, 0xe7, 13, 0x33, 0x0d, 0x57, 0x0e, 0x57, 0x05, 0x57, 0x02,
0x04, 0x10, 0x0b, 0x02, 0x02,
CMD, 0xe8, 5, 0x30, 0x0d, 0x84, 0x8c, 0x21,
CMD, 0xe9, 5, 0x4b, 0x1a, 0xba, 0x60, 0x11,
CMD, 0xea, 5, 0x4b, 0xba, 0xba, 0x10, 0x11,
CMD, 0xeb, 5, 0x0b, 0x3a, 0xd9, 0x60, 0x11,
CMD, 0xef, 3, 0x00, 0x00, 0x00,
CMD, 0xf0, 18, 0x12, 0x01, 0x21, 0xa5, 0x6c, 0x23, 0x02, 0x01,
0x08, 0x0d, 0x1e, 0xde, 0x5a, 0x93, 0xdc, 0x0d,
0x1e, 0x17,
CMD, 0xf1, 18, 0x12, 0x05, 0x21, 0xb5, 0x8d, 0x24, 0x02, 0x01,
0x08, 0x0d, 0x1a, 0xde, 0x4a, 0x72, 0xdb, 0x0d,
0x1e, 0x17,
CMD, 0xf2, 18, 0x0e, 0x00, 0x30, 0xd6, 0x8f, 0x34, 0x03, 0x07,
0x08, 0x11, 0x1f, 0xcf, 0x29, 0x70, 0xcb, 0x0c,
0x18, 0x17,
CMD, 0xfa, 3, 0x02, 0x00, 0x02,
CMD, 0xf7, 2, 0x00, 0xc0,
CMD, 0x35, 1, 0x00, /* Tearing Effect Line On */
CMD, 0x36, 1, 0x20, /* Memory Access Control */
/* Awake sequence */
CMD, 0x11, 0, /* Sleep Out */
SLEEP, 12, /* 120 ms */
CMD, 0x29, 0, /* Display On */
SLEEP, 1, /* 10 ms */
END
};
static void* seq_init_by_type[] =
{
[LCD_TYPE_38B3] = (void*) lcd_init_seq_0,
[LCD_TYPE_38C4] = (void*) lcd_init_seq_1,
[LCD_TYPE_38D5] = (void*) lcd_init_seq_2,
[LCD_TYPE_38E6] = (void*) lcd_init_seq_3,
[LCD_TYPE_58XX] = (void*) lcd_init_seq_4,
};
#endif /* BOOTLOADER */
static struct lcd_info_rec lcd_info = {
.mpuiface = LCD_MPUIFACE_PAR9,
};
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_PAR9, &lcd_id[0]); // TODO?: MPUIFACE_PAR9
if (lcd_id[1] == 0x58)
{
type = LCD_TYPE_58XX;
}
else if (lcd_id[1] == 0x38)
{
if (lcd_id[2] == 0xb3) type = LCD_TYPE_38B3;
else if (lcd_id[2] == 0xc4) type = LCD_TYPE_38C4;
else if (lcd_id[2] == 0xd5) type = LCD_TYPE_38D5;
else if (lcd_id[2] == 0xe6) type = LCD_TYPE_38E6;
}
if (type != LCD_TYPE_UNKNOWN)
{
lcd_info.lcd_type = type;
//lcd_info.mpuiface = LCD_MPUIFACE_PAR9;
#if defined(HAVE_LCD_SLEEP) || defined(HAVE_LCD_SHUTDOWN)
lcd_info.seq_sleep = seq_sleep_by_type[type];
#endif
#ifdef HAVE_LCD_SLEEP
lcd_info.seq_awake = seq_awake_by_type[type];
#endif
#ifdef BOOTLOADER
lcd_info.seq_init = seq_init_by_type[type];
#endif
return &lcd_info;
}
}
#ifdef BOOTLOADER
while (1) {
uint16_t fatal[] = { 3000,500,500, 0 };
piezo_seq(fatal);
}
#else
/* should not happen */
while (1); // TODO?: what to do? poweroff?
#endif
}

View file

@ -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__ */

View file

@ -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;
}

View file

@ -0,0 +1,130 @@
/***************************************************************************
* __________ __ ___.
* 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)
{
PCON0 = (PCON0 & ~0xff000000) | (enable ? 0x53000000 : 0xee000000);
}
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) */
TACMD = (1 << 1); /* TA_CLR */
TAPRE = 30 - 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 << 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 = 0x0060e | 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

View file

@ -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 <stdbool.h>
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 <inttypes.h>
void piezo_tone(uint32_t period, int32_t duration);
void piezo_seq(uint16_t *seq);
#endif
#endif /* __PIEZO_H__ */

View file

@ -0,0 +1,366 @@
/***************************************************************************
* __________ __ ___.
* 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
// TODO
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)
{
pmu_write(D1671_REG_SYSCTRLA, D1671_SYSCTRLA_GOSTDBY);
}
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
void pmu_set_cpu_voltage(bool high)
{
// TODO
(void) high;
}
#endif
#if (CONFIG_RTC == RTC_NANO3G)
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)
{
pmu_write(D1671_REG_CHCTL,
(pmu_read(D1671_REG_CHCTL) & ~D1671_CHCTL_FASTCHRG) | 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[2];
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)
{
unsigned char status[2];
pmu_read_multiple(D1671_REG_STATUSA, 2, status);
if (status[0] & D1671_STATUSA_VBUS)
usb_insert_int();
else
usb_remove_int();
#if CONFIG_CHARGING
pmu_input_firewire = !!(status[0] & D1671_STATUSA_VADAPTOR);
#endif
#ifdef IPOD_ACCESSORY_PROTOCOL
pmu_input_accessory = !!(status[0] & D1671_STATUSA_INPUT1);
#endif
pmu_input_holdswitch = !(status[1] & D1671_STATUSB_INPUT2);
}
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 */
pmu_write_multiple(D1671_REG_EVENTA, 2, "\xFF\xFF");
/* 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[0] &= ~D1671_IRQMASKA_VBUS; /* USB */
#if CONFIG_CHARGING
ints_msk[0] &= ~D1671_IRQMASKA_VADAPTOR; /* FireWire */
#endif
#ifdef IPOD_ACCESSORY_PROTOCOL
ints_msk[0] &= ~D1671_IRQMASKA_INPUT1; /* Accessory */
#endif
ints_msk[1] &= ~D1671_IRQMASKB_INPUT2; /* Holdswitch */
pmu_write_multiple(D1671_REG_IRQMASKA, 2, ints_msk);
/* clear all interrupts */
pmu_write_multiple(D1671_REG_EVENTA, 2, "\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)
{
// TBC: LDOs ???
pmu_wr(0x1b, 0x14);
pmu_wr(0x16, 0x14);
pmu_wr(0x15, 0x14); // TBC: Vnand = 2000 + val*50 = 3000 mV
pmu_wr(0x18, 0x18); // TBC TBC TBC: Vaccy = 3200 mV ???
pmu_wr(0x10, (pmu_rd(0x10) & 0xdb) | 0x8); // TBC: bit4 is related to NAND, LDO_0x15 on/off ???
// TBC: 0x30, 0x31 y 0x32 seems related to ADC (norboot)
pmu_wr(0x34, 0x72); // TBC: en DA9030: TBATHIGH (0-255, TBAT high temperature threshold
pmu_wr(0x30, pmu_rd(0x30) | 0x20); // TBC: TBATREF ON ???
pmu_wr(0x21, 0x5c); // TBC: CHRG_CTL (max. current and Vbat ???)
pmu_wr(0xb, 0x6);
pmu_wr(0x1d, 0);
/* configure and clear interrupts */
pmu_wr_multiple(D1671_REG_IRQMASKA, 2, "\x42\xBE");
pmu_wr_multiple(D1671_REG_EVENTA, 2, "\xFF\xFF");
/* backlight off */
pmu_wr(D1671_REG_LEDCTL, pmu_rd(D1671_REG_LEDCTL) & ~D1671_LEDCTL_ENABLE);
}
#ifdef BOOTLOADER
bool pmu_is_hibernated(void)
{
return !!(pmu_rd(D1671_REG_EVENTB) & D1671_EVENTB_WARMBOOT);
}
#endif

View file

@ -0,0 +1,142 @@
/***************************************************************************
* __________ __ ___.
* 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 <stdint.h>
#include <stdbool.h>
#include "config.h"
/* undocummented PMU registers */
enum d1671_regs {
D1671_REG_EVENTA = 0x02,
D1671_REG_EVENTB = 0x03,
D1671_REG_STATUSA = 0x04,
D1671_REG_STATUSB = 0x05,
D1671_REG_IRQMASKA = 0x06,
D1671_REG_IRQMASKB = 0x07,
D1671_REG_SYSCTRLA = 0x08,
D1671_REG_LEDCTL = 0x20,
D1671_REG_CHCTL = 0x21, // TBC
D1671_REG_RTCSEC = 0x40, // TBC
};
enum d1671_reg_eventa {
D1671_EVENTA_VBUS = 0x08, /* USB: 0 -> not present */
D1671_EVENTA_VADAPTOR = 0x10, /* FireWire: 0 -> not present */
D1671_EVENTA_INPUT1 = 0x20, /* accessory: 0 -> not present */
D1671_EVENTA_UNK6 = 0x40, // ???
};
enum d1671_reg_eventb {
D1671_EVENTB_INPUT2 = 0x01, /* hold switch: 0 -> locked */
D1671_EVENTB_WARMBOOT = 0x80, // TBC
};
enum d1671_reg_statusa {
D1671_STATUSA_VBUS = 0x08,
D1671_STATUSA_VADAPTOR = 0x10,
D1671_STATUSA_INPUT1 = 0x20,
};
enum d1671_reg_statusb {
D1671_STATUSB_INPUT2 = 0x01,
D1671_STATUSB_WARMBOOT = 0x80,
};
enum d1671_reg_irqmaska {
D1671_IRQMASKA_VBUS = 0x08,
D1671_IRQMASKA_VADAPTOR = 0x10,
D1671_IRQMASKA_INPUT1 = 0x20,
};
enum d1671_reg_irqmaskb {
D1671_IRQMASKB_INPUT2 = 0x01,
D1671_IRQMASKB_WARMBOOT = 0x80,
};
enum d1671_reg_sysctrla {
D1671_SYSCTRLA_GOSTDBY = 0x01,
D1671_SYSCTRLA_GOUNK = 0x02, /* enter unknown state (shutdown?) */
};
enum d1671_reg_ledctl {
D1671_LEDCTL_UNKNOWN = 0x40,
D1671_LEDCTL_ENABLE = 0x80,
};
#define D1671_LEDCTL_OUT_POS 0
#define D1671_LEDCTL_OUT_MASK 0x1f
enum d1671_reg_chctl {
D1671_CHCTL_FASTCHRG = 0x01, /* 100/500mA USB limit */
};
/* GPIO for external PMU interrupt */
#define GPIO_EINT_PMU 0x7b
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__ */

View file

@ -0,0 +1,67 @@
/***************************************************************************
* __________ __ ___.
* 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 <stdbool.h>
#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)
{
pmu_enter_standby();
while(1);
}
#if CONFIG_CHARGING
#ifdef HAVE_USB_CHARGING_ENABLE
void usb_charging_maxcurrent_change(int maxcurrent)
{
bool fast_charge = (maxcurrent >= 500);
pmu_set_usblimit(fast_charge);
}
#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 */

View file

@ -0,0 +1,79 @@
/***************************************************************************
* __________ __ ___.
* 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 */
}
else
{
/* Accessory voltage supply off */
}
}
#endif
#ifdef HAVE_LINEOUT_POWEROFF
void lineout_set(bool enable)
{
/* Call audio hardware driver implementation */
audiohw_enable_lineout(enable);
}
#endif

View file

@ -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;
}

View file

@ -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 <stdint.h>
#include <stdbool.h>
#include "config.h"
#include "cpu.h"
#include "system.h"
#include "serial.h"
#include "s5l87xx.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 */

109
tools/configure vendored
View file

@ -1678,49 +1678,49 @@ cat <<EOF
40) Gigabeat F/X 27) 1G, 2G 51) Sansa e200R 40) Gigabeat F/X 27) 1G, 2G 51) Sansa e200R
41) Gigabeat S 28) Nano 2G 52) Sansa c200 41) Gigabeat S 28) Nano 2G 52) Sansa c200
29) Classic/6G 55) Sansa Clip 29) Classic/6G 55) Sansa Clip
==Olympus= 56) Sansa e200v2 ==Olympus= 80) Nano 3G (WIP) 56) Sansa e200v2
70) M:Robe 50 ==Creative== 57) Sansa m200v4 70) M:Robe 50 57) Sansa m200v4
71) M:Robe 100 89) Zen X-Fi Style 58) Sansa Fuze 71) M:Robe 100 ==Creative== 58) Sansa Fuze
90) Zen Vision:M 30GB 59) Sansa c200v2 89) Zen X-Fi Style 59) Sansa c200v2
==Philips== 91) Zen Vision:M 60GB 60) Sansa Clipv2 ==Philips== 90) Zen Vision:M 30GB 60) Sansa Clipv2
100) GoGear SA9200 92) Zen Vision 61) Sansa View 100) GoGear SA9200 91) Zen Vision:M 60GB 61) Sansa View
101) GoGear HDD1630/ 93) Zen X-Fi2 62) Sansa Clip+ 101) GoGear HDD1630/ 92) Zen Vision 62) Sansa Clip+
HDD1830 94) Zen X-Fi3 63) Sansa Fuze v2 HDD1830 93) Zen X-Fi2 63) Sansa Fuze v2
102) GoGear HDD6330 95) Zen V 64) Sansa Fuze+ 102) GoGear HDD6330 94) Zen X-Fi3 64) Sansa Fuze+
96) Zen X-Fi 65) Sansa Clip Zip 95) Zen V 65) Sansa Clip Zip
==Meizu== 97) Zen Mozaic 66) Sansa Connect ==Meizu== 96) Zen X-Fi 66) Sansa Connect
110) M6SL 98) Zen 110) M6SL 97) Zen Mozaic
111) M6SP ==Lyre project== 111) M6SP 98) Zen ==Lyre project==
112) M3 ==Onda== 130) Lyre proto 1 112) M3 130) Lyre proto 1
120) VX747 131) Mini2440 ==Onda== 131) Mini2440
==Samsung== 121) VX767 ==Samsung== 120) VX747
140) YH-820 122) VX747+ ==Packard Bell== 140) YH-820 121) VX767 ==Packard Bell==
141) YH-920 123) VX777 160) Vibe 500 141) YH-920 122) VX747+ 160) Vibe 500
142) YH-925 142) YH-925 123) VX777
143) YP-S3 ==MPIO== ==ROCKCHIP== 143) YP-S3 ==ROCKCHIP==
170) HD200 180) rk27xx generic ==MPIO== 180) rk27xx generic
==HiFiMAN== 171) HD300 ==HiFiMAN== 170) HD200
190) HM-60x ==HiFi E.T.== 190) HM-60x 171) HD300 ==HiFi E.T.==
191) HM-801 ==Application== 210) MA9 191) HM-801 210) MA9
200) SDL 211) MA9C ==Application== 211) MA9C
==Sony== 201) Android 212) MA8 ==Sony== 200) SDL 212) MA8
219) NWZ-E350 series 202) Nokia N8xx 213) MA8C 219) NWZ-E350 series 201) Android 213) MA8C
220) NWZ-E370/E380 series 203) Nokia N900 220) NWZ-E370/E380 series 202) Nokia N8xx
221) NWZ-E360 series 204) Pandora ==IHIFI== 221) NWZ-E360 series 203) Nokia N900 ==IHIFI==
222) NWZ-E450 series 205) Samsung YP-R0 230) 760 222) NWZ-E450 series 204) Pandora 230) 760
223) NWZ-E460 series 206) Android MIPS 231) 960 223) NWZ-E460 series 205) Samsung YP-R0 231) 960
224) NWZ-E470 series 207) Android x86 250) 770C 224) NWZ-E470 series 206) Android MIPS 250) 770C
225) NWZ-E580 series 208) Samsung YP-R1 251) 770 225) NWZ-E580 series 207) Android x86 251) 770
226) NWZ-A10 series 252) 800 226) NWZ-A10 series 208) Samsung YP-R1 252) 800
227) NW-A20 series ==iBasso== 227) NW-A20 series
228) NWZ-A860 series 232) DX50 ==AgpTek== 228) NWZ-A860 series ==iBasso== ==AgpTek==
229) NWZ-S750 series 233) DX90 240) Rocker 229) NWZ-S750 series 232) DX50 240) Rocker
233) DX90
==FiiO== ==xDuoo== ==AIGO== ==FiiO== ==AIGO==
244) M3K Linux 241) X3 245) Eros Q / K 244) M3K Linux ==xDuoo== 245) Eros Q / K
246) M3K baremetal 242) X3II 247) Eros Q / K native 246) M3K baremetal 241) X3 247) Eros Q / K native
243) X20 (hw1/hw2 bl, all hw rb) 242) X3II (hw1/hw2 bl, all hw rb)
==Shanling== 248) Eros Q / K native ==Shanling== 243) X20 248) Eros Q / K native
260) Q1 (hw3 bl only) 260) Q1 (hw3 bl only)
249) Eros Q / K native 249) Eros Q / K native
(hw4 bl only) (hw4 bl only)
@ -2630,6 +2630,29 @@ fi
t_model="mrobe-100" t_model="mrobe-100"
;; ;;
80|ipodnano3g)
target_id=117
modelname="ipodnano3g"
target="IPOD_NANO3G"
memory=32 # always
arm926ejscc
tool="$rootdir/tools/scramble -add=nn3g"
bmp2rb_mono="$rootdir/tools/bmp2rb -f 0"
bmp2rb_native="$rootdir/tools/bmp2rb -f 4"
output="rockbox.ipod"
appextra="recorder:gui:radio"
plugins="yes"
swcodec="yes"
bootoutput="bootloader-$modelname.ipod"
# toolset is the tools within the tools directory that we build for
# this particular target.
toolset=$ipodbitmaptools
# architecture, manufacturer and model for the target-tree build
t_cpu="arm"
t_manufacturer="s5l8702"
t_model="ipodnano3g"
;;
89|creativezenxfistyle) 89|creativezenxfistyle)
target_id=94 target_id=94
modelname="creativezenxfistyle" modelname="creativezenxfistyle"

View file

@ -107,7 +107,8 @@ void usage(void)
"\t 747p, x777, nn2g, m244, cli+, fuz2, hd20, hd30,\n" "\t 747p, x777, nn2g, m244, cli+, fuz2, hd20, hd30,\n"
"\t ip6g, rk27, clzp, zxf2, zxf3, fuz+, e370, e360,\n" "\t ip6g, rk27, clzp, zxf2, zxf3, fuz+, e370, e360,\n"
"\t zxfi, zmoz, zen, zenv, zxfs, e450, e460,\n" "\t zxfi, zmoz, zen, zenv, zxfs, e450, e460,\n"
"\t e470, e580, a10, a20, a860, s750, e350, xdx3)\n"); "\t e470, e580, a10, a20, a860, s750, e350, xdx3,\n"
"\t nn3g)\n");
printf("\nNo option results in nothing being done.\n"); printf("\nNo option results in nothing being done.\n");
exit(1); exit(1);
@ -231,8 +232,8 @@ int main (int argc, char** argv)
modelnum = 25; modelnum = 25;
else if (!strcmp(&argv[1][5], "m200")) else if (!strcmp(&argv[1][5], "m200"))
modelnum = 29; modelnum = 29;
else if(!strcmp(&argv[1][5], "c100")) else if(!strcmp(&argv[1][5], "c100"))
modelnum = 30; modelnum = 30;
else if(!strcmp(&argv[1][5], "1630")) /* Philips HDD1630 */ else if(!strcmp(&argv[1][5], "1630")) /* Philips HDD1630 */
modelnum = 31; modelnum = 31;
else if (!strcmp(&argv[1][5], "i7")) else if (!strcmp(&argv[1][5], "i7"))
@ -335,6 +336,8 @@ int main (int argc, char** argv)
modelnum = 115; modelnum = 115;
else if (!strcmp(&argv[1][5], "erosqnative")) /* Aigo Eros Q Native */ else if (!strcmp(&argv[1][5], "erosqnative")) /* Aigo Eros Q Native */
modelnum = 116; modelnum = 116;
else if (!strcmp(&argv[1][5], "nn3g")) /* iPod Nano 3rd Gen */
modelnum = 117;
else { else {
fprintf(stderr, "unsupported model: %s\n", &argv[1][5]); fprintf(stderr, "unsupported model: %s\n", &argv[1][5]);
return 2; return 2;
@ -440,7 +443,7 @@ int main (int argc, char** argv)
int mi4magic; int mi4magic;
char model[4] = ""; char model[4] = "";
char type[4] = ""; char type[4] = "";
if(!strcmp(&argv[1][4], "v2")) { if(!strcmp(&argv[1][4], "v2")) {
mi4magic = MI4_MAGIC_DEFAULT; mi4magic = MI4_MAGIC_DEFAULT;
version = 0x00010201; version = 0x00010201;
@ -460,12 +463,12 @@ int main (int argc, char** argv)
iname = argv[2]; iname = argv[2];
oname = argv[3]; oname = argv[3];
if(!strncmp(argv[2], "-model=", 7)) { if(!strncmp(argv[2], "-model=", 7)) {
iname = argv[3]; iname = argv[3];
oname = argv[4]; oname = argv[4];
strncpy(model, &argv[2][7], 4); strncpy(model, &argv[2][7], 4);
if(!strncmp(argv[3], "-type=", 6)) { if(!strncmp(argv[3], "-type=", 6)) {
iname = argv[4]; iname = argv[4];
oname = argv[5]; oname = argv[5];
@ -475,7 +478,7 @@ int main (int argc, char** argv)
return mi4_encode(iname, oname, version, mi4magic, model, type); return mi4_encode(iname, oname, version, mi4magic, model, type);
} }
/* open file */ /* open file */
file = fopen(iname,"rb"); file = fopen(iname,"rb");
if (!file) { if (!file) {
@ -485,9 +488,9 @@ int main (int argc, char** argv)
fseek(file,0,SEEK_END); fseek(file,0,SEEK_END);
length = ftell(file); length = ftell(file);
length = (length + 3) & ~3; /* Round up to nearest 4 byte boundary */ length = (length + 3) & ~3; /* Round up to nearest 4 byte boundary */
fseek(file,0,SEEK_SET);
fseek(file,0,SEEK_SET);
inbuf = malloc(length); inbuf = malloc(length);
if(method == add) if(method == add)
outbuf = malloc(length + 8); outbuf = malloc(length + 8);
@ -582,10 +585,10 @@ int main (int argc, char** argv)
return -1; return -1;
} }
fclose(file); fclose(file);
free(inbuf); free(inbuf);
free(outbuf); free(outbuf);
return 0; return 0;
} }
@ -597,7 +600,7 @@ static int iaudio_encode(char *iname, char *oname, char *idstring)
unsigned char *outbuf; unsigned char *outbuf;
int i; int i;
unsigned char sum = 0; unsigned char sum = 0;
file = fopen(iname, "rb"); file = fopen(iname, "rb");
if (!file) { if (!file) {
perror(iname); perror(iname);
@ -605,8 +608,8 @@ static int iaudio_encode(char *iname, char *oname, char *idstring)
} }
fseek(file,0,SEEK_END); fseek(file,0,SEEK_END);
length = ftell(file); length = ftell(file);
fseek(file,0,SEEK_SET); fseek(file,0,SEEK_SET);
outbuf = malloc(length+0x1030); outbuf = malloc(length+0x1030);
if ( !outbuf ) { if ( !outbuf ) {
@ -619,10 +622,10 @@ static int iaudio_encode(char *iname, char *oname, char *idstring)
perror(iname); perror(iname);
return -2; return -2;
} }
memset(outbuf, 0, 0x1030); memset(outbuf, 0, 0x1030);
strcpy((char *)outbuf, idstring); strcpy((char *)outbuf, idstring);
memcpy(outbuf+0x20, iaudio_bl_flash, memcpy(outbuf+0x20, iaudio_bl_flash,
BMPWIDTH_iaudio_bl_flash * (BMPHEIGHT_iaudio_bl_flash/8) * 2); BMPWIDTH_iaudio_bl_flash * (BMPHEIGHT_iaudio_bl_flash/8) * 2);
short2be(BMPWIDTH_iaudio_bl_flash, &outbuf[0x10]); short2be(BMPWIDTH_iaudio_bl_flash, &outbuf[0x10]);
short2be((BMPHEIGHT_iaudio_bl_flash/8), &outbuf[0x12]); short2be((BMPHEIGHT_iaudio_bl_flash/8), &outbuf[0x12]);
@ -641,7 +644,7 @@ static int iaudio_encode(char *iname, char *oname, char *idstring)
perror(oname); perror(oname);
return -3; return -3;
} }
len = fwrite(outbuf, 1, length+0x1030, file); len = fwrite(outbuf, 1, length+0x1030, file);
if(len < (size_t)length) { if(len < (size_t)length) {
perror(oname); perror(oname);
@ -653,14 +656,14 @@ static int iaudio_encode(char *iname, char *oname, char *idstring)
} }
/* Create an ipod firmware partition image /* Create an ipod firmware partition image
fw_ver = 2 for 3rd Gen ipods, 3 for all later ipods including 5g. fw_ver = 2 for 3rd Gen ipods, 3 for all later ipods including 5g.
This function doesn't yet handle the Broadcom resource image for the 5g, This function doesn't yet handle the Broadcom resource image for the 5g,
so the resulting images won't be usable. so the resulting images won't be usable.
This has also only been tested on an ipod Photo This has also only been tested on an ipod Photo
*/ */
static int ipod_encode(char *iname, char *oname, int fw_ver, bool fake_rsrc) static int ipod_encode(char *iname, char *oname, int fw_ver, bool fake_rsrc)
@ -699,7 +702,7 @@ static int ipod_encode(char *iname, char *oname, int fw_ver, bool fake_rsrc)
} }
fseek(file,0,SEEK_END); fseek(file,0,SEEK_END);
length = ftell(file); length = ftell(file);
fseek(file,0,SEEK_SET); fseek(file,0,SEEK_SET);
bufsize=(length+0x4600); bufsize=(length+0x4600);
@ -721,7 +724,7 @@ static int ipod_encode(char *iname, char *oname, int fw_ver, bool fake_rsrc)
} }
fclose(file); fclose(file);
/* Calculate checksum for later use in header */ /* Calculate checksum for later use in header */
for(i = 0x4600; i < 0x4600+length;i++) for(i = 0x4600; i < 0x4600+length;i++)
sum += outbuf[i]; sum += outbuf[i];
@ -770,7 +773,7 @@ static int ipod_encode(char *iname, char *oname, int fw_ver, bool fake_rsrc)
perror(oname); perror(oname);
return -3; return -3;
} }
len = fwrite(outbuf, 1, length+0x4600, file); len = fwrite(outbuf, 1, length+0x4600, file);
if(len < (size_t)length) { if(len < (size_t)length) {
perror(oname); perror(oname);
@ -797,7 +800,7 @@ static int ccpmp_encode(char *iname, char *oname)
} }
fseek(file,0,SEEK_END); fseek(file,0,SEEK_END);
length = ftell(file); length = ftell(file);
fseek(file,0,SEEK_SET); fseek(file,0,SEEK_SET);
outbuf = malloc(CCPMP_SIZE); outbuf = malloc(CCPMP_SIZE);
@ -825,7 +828,7 @@ static int ccpmp_encode(char *iname, char *oname)
perror(oname); perror(oname);
return -3; return -3;
} }
len = fwrite(outbuf, 1, CCPMP_SIZE, file); len = fwrite(outbuf, 1, CCPMP_SIZE, file);
if(len < (size_t)length) { if(len < (size_t)length) {
perror(oname); perror(oname);