1
0
Fork 0
forked from len0rd/rockbox

Start of a Rockbox port to the Samsung YP-S3.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@22085 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Bertrik Sikken 2009-07-29 20:42:02 +00:00
parent e30f1e83c4
commit 2fb73842a9
11 changed files with 1141 additions and 0 deletions

View file

@ -0,0 +1,78 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* 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 <stdbool.h>
#include "config.h"
#include "backlight.h"
#include "backlight-target.h"
#include "system.h"
/*
Backlight driver using the PWM mode of a hardware timer.
The PWM duty cycle depends exponentially on the configured brightness
level. This makes the brightness curve more linear to the human eye.
*/
void _backlight_set_brightness(int brightness)
{
/* pwm = (sqrt(2)**x)-1, where brightness level x = 0..16 */
static const unsigned char logtable[] =
{0, 1, 2, 3, 5, 7, 10, 15, 22, 31, 44, 63, 90, 127, 180, 255};
/* set PWM width */
TADATA0 = 255 - logtable[brightness];
}
void _backlight_on(void)
{
_backlight_set_brightness(backlight_brightness);
}
void _backlight_off(void)
{
_backlight_set_brightness(MIN_BRIGHTNESS_SETTING);
}
bool _backlight_init(void)
{
/* enable backlight pin as timer output */
PCON0 = ((PCON0 & ~(3 << 0)) | (2 << 0));
/* enable timer clock */
PWRCON &= ~(1 << 4);
/* configure timer */
TACMD = (1 << 1); /* TC_CLR */
TACON = (0 << 13) | /* TC_INT1_EN */
(0 << 12) | /* TC_INT0_EN */
(0 << 11) | /* TC_START */
(3 << 8) | /* TC_CS = PCLK / 64 */
(1 << 4); /* TC_MODE_SEL = PWM mode */
TADATA1 = 255; /* set PWM period */
TAPRE = 20; /* prescaler */
TACMD = (1 << 0); /* TC_EN */
_backlight_on();
return true;
}

View file

@ -0,0 +1,50 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* 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.
*
****************************************************************************/
#ifndef _BUTTON_TARGET_H_
#define _BUTTON_TARGET_H_
#include <stdbool.h>
#define HAS_BUTTON_HOLD
bool button_hold(void);
void button_init_device(void);
int button_read_device(void);
#define BUTTON_BACK 0x00000001
#define BUTTON_MENU 0x00000002
#define BUTTON_UP 0x00000004
#define BUTTON_DOWN 0x00000008
#define BUTTON_LEFT 0x00000010
#define BUTTON_RIGHT 0x00000020
#define BUTTON_SELECT 0x00000040
#define BUTTON_POWER 0x00000080
#define BUTTON_MAIN (BUTTON_BACK|BUTTON_MENU|BUTTON_UP|BUTTON_DOWN|BUTTON_LEFT|\
BUTTON_RIGHT|BUTTON_SELECT)
#define BUTTON_REMOTE 0
#define POWEROFF_BUTTON BUTTON_POWER
#define POWEROFF_COUNT 10
#endif /* _BUTTON_TARGET_H_ */

View file

@ -0,0 +1,46 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* 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.
*
****************************************************************************/
/*
FM radio i2c interface, allows the radio driver to talk to the tuner chip.
*/
#include "config.h"
#include "i2c-s5l8700.h"
#include "fmradio_i2c.h"
void fmradio_i2c_init(void)
{
/* nothing to do */
}
int fmradio_i2c_write(unsigned char address, const unsigned char* buf, int count)
{
return i2c_write(address, -1, count, buf);
}
int fmradio_i2c_read(unsigned char address, unsigned char* buf, int count)
{
return i2c_read(address, -1, count, buf);
}

View file

@ -0,0 +1,336 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* 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 "s5l8700.h"
#include "lcd.h"
/* LCD driver for the Samsung YP-S3
It appears that this player can contain two display types.
Detection of the display type is done by looking at the level of pin P0.4.
Currently only display "type 2" has been implemented and tested.
This driver could use DMA to do the screen updates, but currently writes
the data to the LCD using the processor instead.
*/
static int lcd_type = 0;
static void lcd_delay(int delay)
{
volatile int i;
for (i = 0; i < delay; i++);
}
static void lcd_reset_delay(void)
{
lcd_delay(10000);
}
static void lcd_reset(void)
{
LCD_CON = 0xDB8;
LCD_PHTIME = 0x22;
LCD_RST_TIME = 0x7FFF;
lcd_reset_delay();
LCD_DRV_RST = 0;
lcd_reset_delay();
LCD_DRV_RST = 1;
lcd_reset_delay();
LCD_DRV_RST = 0;
lcd_reset_delay();
LCD_DRV_RST = 1;
LCD_INTCON = 0;
}
static void lcd_wcmd(unsigned int cmd)
{
while ((LCD_STATUS & 0x10) != 0);
LCD_WCMD = cmd;
}
static void lcd_wdata(unsigned int data)
{
while ((LCD_STATUS & 0x10) != 0);
LCD_WDATA = data;
}
static void lcd_wcmd_data(unsigned int cmd, unsigned int data)
{
lcd_wcmd(cmd);
lcd_wdata(data);
}
void lcd_init1(void)
{
lcd_wcmd(0x11);
lcd_delay(10000);
lcd_wcmd(0xF0);
lcd_wdata(0x5A);
lcd_wcmd(0xC0);
lcd_wdata(0x05);
lcd_wdata(0x01);
lcd_wcmd(0xC1);
lcd_wdata(0x04);
lcd_wcmd(0xC5);
lcd_wdata(0xB0);
lcd_wcmd(0xC6);
lcd_wdata(0x0);
lcd_wcmd(0xB1);
lcd_wdata(0x02);
lcd_wdata(0x0E);
lcd_wdata(0x00);
lcd_wcmd(0xF2);
lcd_wdata(0x01);
lcd_wcmd(0xE0);
lcd_wdata(0x09);
lcd_wdata(0x00);
lcd_wdata(0x06);
lcd_wdata(0x2E);
lcd_wdata(0x2B);
lcd_wdata(0x0B);
lcd_wdata(0x1A);
lcd_wdata(0x02);
lcd_wdata(0x06);
lcd_wdata(0x0C);
lcd_wdata(0x0D);
lcd_wdata(0x00);
lcd_wdata(0x05);
lcd_wdata(0x02);
lcd_wdata(0x05);
lcd_wcmd(0xE1);
lcd_wdata(0x06);
lcd_wdata(0x23);
lcd_wdata(0x25);
lcd_wdata(0x0F);
lcd_wdata(0x0A);
lcd_wdata(0x04);
lcd_wdata(0x02);
lcd_wdata(0x1A);
lcd_wdata(0x05);
lcd_wdata(0x03);
lcd_wdata(0x06);
lcd_wdata(0x01);
lcd_wdata(0x0C);
lcd_wdata(0x0B);
lcd_wdata(0x05);
lcd_wdata(0x05);
lcd_wcmd(0x3A);
lcd_wdata(0x05);
lcd_wcmd(0x29);
lcd_wcmd(0x2C);
}
void lcd_init2(void)
{
lcd_wcmd_data(0x00, 0x0001);
lcd_delay(50000);
lcd_wcmd_data(0x07, 0x0000);
lcd_wcmd_data(0x12, 0x0000);
lcd_delay(10000);
lcd_wcmd(0);
lcd_wcmd(0);
lcd_wcmd(0);
lcd_wcmd(0);
lcd_wcmd_data(0xA4, 0x0001);
lcd_delay(10000);
lcd_wcmd_data(0x70, 0x1B00);
lcd_wcmd_data(0x08, 0x030A);
lcd_wcmd_data(0x30, 0x0000);
lcd_wcmd_data(0x31, 0x0305);
lcd_wcmd_data(0x32, 0x0304);
lcd_wcmd_data(0x33, 0x0107);
lcd_wcmd_data(0x34, 0x0304);
lcd_wcmd_data(0x35, 0x0204);
lcd_wcmd_data(0x36, 0x0707);
lcd_wcmd_data(0x37, 0x0701);
lcd_wcmd_data(0x38, 0x1B08);
lcd_wcmd_data(0x39, 0x030F);
lcd_wcmd_data(0x3A, 0x0E0E);
lcd_wcmd_data(0x07, 0x0001);
lcd_delay(50000);
lcd_wcmd_data(0x18, 0x0001);
lcd_wcmd_data(0x10, 0x12B0);
lcd_wcmd_data(0x11, 0x0001);
lcd_wcmd_data(0x12, 0x0114);
lcd_wcmd_data(0x13, 0x8D0F);
lcd_wcmd_data(0x12, 0x0134);
lcd_delay(1000);
lcd_wcmd_data(0x01, 0x0100);
lcd_wcmd_data(0x02, 0x0700);
lcd_wcmd_data(0x03, 0x5030);
lcd_wcmd_data(0x04, 0x0000);
lcd_wcmd_data(0x09, 0x0000);
lcd_wcmd_data(0x0C, 0x0000);
lcd_wcmd_data(0x0F, 0x0000);
lcd_wcmd_data(0x14, 0x8000);
lcd_wcmd_data(0x20, 0x0000);
lcd_wcmd_data(0x21, 0x0000);
lcd_wcmd_data(0x71, 0x0001);
lcd_wcmd_data(0x7A, 0x0000);
lcd_wcmd_data(0x90, 0x0000);
lcd_wcmd_data(0x91, 0x0100);
lcd_wcmd_data(0x92, 0x0000);
lcd_wcmd_data(0x98, 0x0001);
lcd_wcmd_data(0x99, 0x030C);
lcd_wcmd_data(0x9A, 0x030C);
lcd_delay(50000);
lcd_wcmd_data(0x07, 0x0001);
lcd_delay(30000);
lcd_wcmd_data(0x07, 0x0021);
lcd_wcmd_data(0x12, 0x1134);
lcd_delay(10000);
lcd_wcmd_data(0x07, 0x0233);
lcd_delay(30000);
}
void lcd_set_window1(int x, int y, int width, int height)
{
(void)x;
(void)width;
lcd_wcmd(0x2A);
lcd_wdata(0);
lcd_wdata(y);
lcd_wdata(0);
lcd_wcmd(0x2B);
lcd_wdata(0);
lcd_wdata(y + height - 1);
lcd_wdata(0);
}
void lcd_set_window2(int x, int y, int width, int height)
{
lcd_wcmd_data(0x50, x);
lcd_wcmd_data(0x51, x + width - 1);
lcd_wcmd_data(0x52, y);
lcd_wcmd_data(0x53, y + height - 1);
}
static void lcd_set_position1(int x, int y)
{
(void)x;
(void)y;
}
static void lcd_set_position2(int x, int y)
{
lcd_wcmd_data(0x20, x);
lcd_wcmd_data(0x21, y);
lcd_wcmd(0x22);
}
void lcd_init_device(void)
{
/* enable LCD clock */
PWRCON &= ~(1 << 18);
/* configure LCD pins */
PCON0 &= ~(3 << 8);
PCON7 = (PCON7 & ~(0x000000FF)) | 0x00000033;
PCON_ASRAM = 2;
lcd_reset();
/* detect LCD type on P0.4 */
lcd_type = (PDAT0 & (1 << 4)) ? 1 : 2;
/* initialise display */
if (lcd_type == 1) {
lcd_init1();
} else {
lcd_init2();
}
}
void lcd_update_rect(int x, int y, int width, int height)
{
fb_data* p;
int h, w;
if (lcd_type == 1) {
/* TODO implement and test */
lcd_set_window1(x, y, width, height);
lcd_set_position1(x, y);
for (h = 0; h < height; h++) {
p = &lcd_framebuffer[y][0];
for (w = 0; w < LCD_WIDTH; w++) {
while (LCD_STATUS & 0x10);
LCD_WDATA = *p++;
}
y++;
}
}
else {
lcd_set_window2(x, y, width, height);
lcd_set_position2(x, y);
for (h = 0; h < height; h++) {
p = &lcd_framebuffer[y][x];
for (w = 0; w < width; w++) {
while (LCD_STATUS & 0x10);
LCD_WDATA = *p++;
}
y++;
}
}
}
void lcd_update(void)
{
lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
}

View file

@ -0,0 +1,95 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* 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 "s5l8700.h"
#include "power.h"
/* Power handling for the S5L8700 based Samsung YP-S3
Pins involved in with power management:
* P1.1: USB power detect
* P4.7: tuner power/enable
* P5.2: unknown output
* P5.3: unknown output, related to charging (perhaps charge current?)
* P5.4: charge status input (only valid if charger enabled)
* P5.6: charger enable
*/
void power_off(void)
{
/* don't know how to do this yet */
}
void power_init(void)
{
/* configure pin P1.1 as input for USB power detect */
PCON1 = (PCON1 & ~0x000000F0) | 0x00000000;
/* enable tuner power pin on P4.7 and turn power off */
PCON4 = (PCON4 & ~0xF0000000) | 0x10000000;
PDAT4 &= ~(1 << 7);
/* configure pins P5.2 / P5.3 / P5.6 as output, P5.4 as input */
PCON5 = (PCON5 & ~0x0F0FFF00) | 0x01001100;
PDAT5 &= ~((1 << 2) | (1 << 3) | (1 << 6));
}
#if CONFIG_CHARGING
unsigned int power_input_status(void)
{
/* check USB power on P1.1 */
if (PDAT1 & (1 << 1)) {
return POWER_INPUT_USB;
}
return POWER_INPUT_NONE;
}
bool charging_state(void)
{
if (PDAT5 & (1 << 6)) {
/* charger is enabled, check if charging is busy */
return (PDAT5 & (1 << 4));
}
return false;
}
#endif /* CONFIG_CHARGING */
#if CONFIG_TUNER
bool tuner_power(bool status)
{
if (status) {
PDAT4 |= (1 << 7);
}
else {
PDAT4 &= ~(1 << 7);
}
/* TODO what should we return here? */
return status;
}
bool tuner_powered(void)
{
return (PDAT4 & (1 << 7));
}
#endif /* CONFIG_TUNER */