summaryrefslogtreecommitdiff
path: root/firmware/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers')
-rw-r--r--firmware/drivers/audio/mas35xx.c285
-rw-r--r--firmware/drivers/audio/sdl.c22
-rw-r--r--firmware/drivers/button.c9
-rw-r--r--firmware/drivers/fmradio.c121
-rw-r--r--firmware/drivers/rtc/rtc_m41st84w.c296
-rw-r--r--firmware/drivers/tuner/s1a0903x01.c179
6 files changed, 0 insertions, 912 deletions
diff --git a/firmware/drivers/audio/mas35xx.c b/firmware/drivers/audio/mas35xx.c
deleted file mode 100644
index 65c582c79c..0000000000
--- a/firmware/drivers/audio/mas35xx.c
+++ /dev/null
@@ -1,285 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Driver for MAS35xx audio codec
11 *
12 *
13 * Copyright (c) 2007 by Christian Gmeiner
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * KIND, either express or implied.
22 *
23 ****************************************************************************/
24
25#include "config.h"
26#include "system.h" /* MAX MIN macros */
27#include "sound.h"
28
29int channel_configuration = SOUND_CHAN_STEREO;
30int stereo_width = 100;
31
32#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
33unsigned long mdb_shape_shadow = 0;
34unsigned long loudness_shadow = 0;
35unsigned long shadow_io_control_main;
36#endif
37
38static void set_channel_config(void)
39{
40 /* default values: stereo */
41 unsigned long val_ll = 0x80000;
42 unsigned long val_lr = 0;
43 unsigned long val_rl = 0;
44 unsigned long val_rr = 0x80000;
45 int bank;
46
47 switch(channel_configuration)
48 {
49 /* case SOUND_CHAN_STEREO unnecessary */
50
51 case SOUND_CHAN_MONO:
52 val_ll = 0xc0000;
53 val_lr = 0xc0000;
54 val_rl = 0xc0000;
55 val_rr = 0xc0000;
56 break;
57
58 case SOUND_CHAN_CUSTOM:
59 {
60 /* fixed point variables (matching MAS internal format)
61 integer part: upper 13 bits (inlcuding sign)
62 fractional part: lower 19 bits */
63 long fp_width, fp_straight, fp_cross;
64
65 fp_width = (stereo_width << 19) / 100;
66 if (stereo_width <= 100)
67 {
68 fp_straight = - ((1<<19) + fp_width) / 2;
69 fp_cross = fp_straight + fp_width;
70 }
71 else
72 {
73 /* straight = - (1 + width) / (2 * width) */
74 fp_straight = - ((((1<<19) + fp_width) / (fp_width >> 9)) << 9);
75 fp_cross = (1<<19) + fp_straight;
76 }
77 val_ll = val_rr = fp_straight & 0xfffff;
78 val_lr = val_rl = fp_cross & 0xfffff;
79 }
80 break;
81
82 case SOUND_CHAN_MONO_LEFT:
83 val_ll = 0x80000;
84 val_lr = 0x80000;
85 val_rl = 0;
86 val_rr = 0;
87 break;
88
89 case SOUND_CHAN_MONO_RIGHT:
90 val_ll = 0;
91 val_lr = 0;
92 val_rl = 0x80000;
93 val_rr = 0x80000;
94 break;
95
96 case SOUND_CHAN_KARAOKE:
97 val_ll = 0xc0000;
98 val_lr = 0x40000;
99 val_rl = 0x40000;
100 val_rr = 0xc0000;
101 break;
102 }
103
104#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
105 bank = MAS_BANK_D0;
106#elif CONFIG_CODEC == MAS3507D
107 bank = MAS_BANK_D1;
108#endif
109
110 mas_writemem(bank, MAS_D0_OUT_LL, &val_ll, 1); /* LL */
111 mas_writemem(bank, MAS_D0_OUT_LR, &val_lr, 1); /* LR */
112 mas_writemem(bank, MAS_D0_OUT_RL, &val_rl, 1); /* RL */
113 mas_writemem(bank, MAS_D0_OUT_RR, &val_rr, 1); /* RR */
114}
115
116void audiohw_set_channel(int val)
117{
118 channel_configuration = val;
119 set_channel_config();
120}
121
122void audiohw_set_stereo_width(int val)
123{
124 stereo_width = val;
125 if (channel_configuration == SOUND_CHAN_CUSTOM) {
126 set_channel_config();
127 }
128}
129
130void audiohw_set_bass(int val)
131{
132#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
133 unsigned tmp = ((unsigned)(val * 8) & 0xff) << 8;
134 mas_codec_writereg(MAS_REG_KBASS, tmp);
135#elif CONFIG_CODEC == MAS3507D
136 mas_writereg(MAS_REG_KBASS, bass_table[val+15]);
137#endif
138}
139
140#if CONFIG_CODEC == MAS3507D
141void audiohw_set_prescaler(int val)
142{
143 mas_writereg(MAS_REG_KPRESCALE, prescale_table[val/10]);
144}
145#endif
146
147void audiohw_set_treble(int val)
148{
149#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
150 unsigned tmp = ((unsigned)(val * 8) & 0xff) << 8;
151 mas_codec_writereg(MAS_REG_KTREBLE, tmp);
152#elif CONFIG_CODEC == MAS3507D
153 mas_writereg(MAS_REG_KTREBLE, treble_table[val+15]);
154#endif
155}
156
157#if (CONFIG_CODEC == MAS3507D)
158/* convert tenth of dB volume (-780..+180) to dac3550 register value */
159static unsigned int tenthdb2reg(int db)
160{
161 if (db < -540) /* 3 dB steps */
162 return (db + 780) / 30;
163 else /* 1.5 dB steps */
164 return (db + 660) / 15;
165}
166
167void audiohw_set_volume(int vol_l, int vol_r)
168{
169 dac_volume(tenthdb2reg(vol_l), tenthdb2reg(vol_r), false);
170}
171#endif /* CONFIG_CODEC == MAS3507D */
172
173#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
174void audiohw_set_volume(int val)
175{
176 unsigned tmp = ((unsigned)(val + 115) & 0xff) << 8;
177 mas_codec_writereg(MAS_REG_VOLUME_CONTROL, tmp);
178}
179
180void audiohw_set_loudness(int value)
181{
182 loudness_shadow = (loudness_shadow & 0x04) |
183 (MAX(MIN(value * 4, 0x44), 0) << 8);
184 mas_codec_writereg(MAS_REG_KLOUDNESS, loudness_shadow);
185}
186
187void audiohw_set_avc(int value)
188{
189 int tmp;
190
191 static const uint16_t avc_vals[] =
192 {
193 (0x1 << 8) | (0x8 << 12), /* 20ms */
194 (0x2 << 8) | (0x8 << 12), /* 2s */
195 (0x4 << 8) | (0x8 << 12), /* 4s */
196 (0x8 << 8) | (0x8 << 12), /* 8s */
197 };
198 switch (value) {
199 case 1:
200 case 2:
201 case 3:
202 case 4:
203 tmp = avc_vals[value -1];
204 break;
205 case -1: /* turn off and then turn on again to decay quickly */
206 tmp = mas_codec_readreg(MAS_REG_KAVC);
207 mas_codec_writereg(MAS_REG_KAVC, 0);
208 break;
209 default: /* off */
210 tmp = 0;
211 break;
212 }
213 mas_codec_writereg(MAS_REG_KAVC, tmp);
214}
215
216void audiohw_set_mdb_strength(int value)
217{
218 mas_codec_writereg(MAS_REG_KMDB_STR, (value & 0x7f) << 8);
219}
220
221void audiohw_set_mdb_harmonics(int value)
222{
223 int tmp = value * 127 / 100;
224 mas_codec_writereg(MAS_REG_KMDB_HAR, (tmp & 0x7f) << 8);
225}
226
227void audiohw_set_mdb_center(int value)
228{
229 mas_codec_writereg(MAS_REG_KMDB_FC, (value/10) << 8);
230}
231
232void audiohw_set_mdb_shape(int value)
233{
234 mdb_shape_shadow = (mdb_shape_shadow & 0x02) | ((value/10) << 8);
235 mas_codec_writereg(MAS_REG_KMDB_SWITCH, mdb_shape_shadow);
236}
237
238void audiohw_set_mdb_enable(int value)
239{
240 mdb_shape_shadow = (mdb_shape_shadow & ~0x02) | (value?2:0);
241 mas_codec_writereg(MAS_REG_KMDB_SWITCH, mdb_shape_shadow);
242}
243
244void audiohw_set_superbass(int value)
245{
246 loudness_shadow = (loudness_shadow & ~0x04) | (value?4:0);
247 mas_codec_writereg(MAS_REG_KLOUDNESS, loudness_shadow);
248}
249
250void audiohw_set_balance(int val)
251{
252 unsigned tmp = ((unsigned)(val * 127 / 100) & 0xff) << 8;
253 mas_codec_writereg(MAS_REG_BALANCE, tmp);
254}
255
256/* This functionality works by telling the decoder that we have another
257 crystal frequency than we actually have. It will adjust its internal
258 parameters and the result is that the audio is played at another pitch.
259*/
260static int32_t last_pitch = PITCH_SPEED_100;
261
262void audiohw_set_pitch(int32_t val)
263{
264 if (val == last_pitch)
265 return;
266
267 /* Calculate the new (bogus) frequency */
268 unsigned long reg = 18432 * PITCH_SPEED_100 / val;
269 mas_writemem(MAS_BANK_D0, MAS_D0_OFREQ_CONTROL, &reg, 1);
270
271 /* We must tell the MAS that the frequency has changed.
272 * This will unfortunately cause a short silence. */
273 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN,
274 &shadow_io_control_main, 1);
275
276 last_pitch = val;
277}
278
279int32_t audiohw_get_pitch(void)
280{
281 return last_pitch;
282}
283
284#endif /* CONFIG_CODEC == MAS3587F || CONFIG_CODEC == MAS3539F */
285
diff --git a/firmware/drivers/audio/sdl.c b/firmware/drivers/audio/sdl.c
index a8fd2ffa07..d701665889 100644
--- a/firmware/drivers/audio/sdl.c
+++ b/firmware/drivers/audio/sdl.c
@@ -134,25 +134,3 @@ unsigned int pcm_sampr_to_hw_sampr(unsigned int samplerate,
134 unsigned int type) 134 unsigned int type)
135 { return samplerate; (void)type; } 135 { return samplerate; (void)type; }
136#endif /* CONFIG_SAMPR_TYPES */ 136#endif /* CONFIG_SAMPR_TYPES */
137#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
138int mas_codec_readreg(int reg)
139{
140 (void)reg;
141 return 0;
142}
143
144int mas_codec_writereg(int reg, unsigned int val)
145{
146 (void)reg;
147 (void)val;
148 return 0;
149}
150int mas_writemem(int bank, int addr, const unsigned long* src, int len)
151{
152 (void)bank;
153 (void)addr;
154 (void)src;
155 (void)len;
156 return 0;
157}
158#endif
diff --git a/firmware/drivers/button.c b/firmware/drivers/button.c
index 626afc415f..c81b629f6d 100644
--- a/firmware/drivers/button.c
+++ b/firmware/drivers/button.c
@@ -575,9 +575,6 @@ static int button_flip(int button)
575#if defined(BUTTON_SCROLL_BACK) && defined(BUTTON_SCROLL_FWD) 575#if defined(BUTTON_SCROLL_BACK) && defined(BUTTON_SCROLL_FWD)
576 | BUTTON_SCROLL_BACK | BUTTON_SCROLL_FWD 576 | BUTTON_SCROLL_BACK | BUTTON_SCROLL_FWD
577#endif 577#endif
578#if CONFIG_KEYPAD == RECORDER_PAD
579 | BUTTON_F1 | BUTTON_F3
580#endif
581#if (CONFIG_KEYPAD == SANSA_C200_PAD) || (CONFIG_KEYPAD == SANSA_CLIP_PAD) ||\ 578#if (CONFIG_KEYPAD == SANSA_C200_PAD) || (CONFIG_KEYPAD == SANSA_CLIP_PAD) ||\
582 (CONFIG_KEYPAD == GIGABEAT_PAD) || (CONFIG_KEYPAD == GIGABEAT_S_PAD) 579 (CONFIG_KEYPAD == GIGABEAT_PAD) || (CONFIG_KEYPAD == GIGABEAT_S_PAD)
583 | BUTTON_VOL_UP | BUTTON_VOL_DOWN 580 | BUTTON_VOL_UP | BUTTON_VOL_DOWN
@@ -604,12 +601,6 @@ static int button_flip(int button)
604 if (button & BUTTON_SCROLL_FWD) 601 if (button & BUTTON_SCROLL_FWD)
605 newbutton |= BUTTON_SCROLL_BACK; 602 newbutton |= BUTTON_SCROLL_BACK;
606#endif 603#endif
607#if CONFIG_KEYPAD == RECORDER_PAD
608 if (button & BUTTON_F1)
609 newbutton |= BUTTON_F3;
610 if (button & BUTTON_F3)
611 newbutton |= BUTTON_F1;
612#endif
613#if (CONFIG_KEYPAD == SANSA_C200_PAD) || (CONFIG_KEYPAD == SANSA_CLIP_PAD) ||\ 604#if (CONFIG_KEYPAD == SANSA_C200_PAD) || (CONFIG_KEYPAD == SANSA_CLIP_PAD) ||\
614 (CONFIG_KEYPAD == GIGABEAT_PAD) || (CONFIG_KEYPAD == GIGABEAT_S_PAD) 605 (CONFIG_KEYPAD == GIGABEAT_PAD) || (CONFIG_KEYPAD == GIGABEAT_S_PAD)
615 if (button & BUTTON_VOL_UP) 606 if (button & BUTTON_VOL_UP)
diff --git a/firmware/drivers/fmradio.c b/firmware/drivers/fmradio.c
deleted file mode 100644
index a6d2e799cb..0000000000
--- a/firmware/drivers/fmradio.c
+++ /dev/null
@@ -1,121 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "lcd.h"
22#include "sh7034.h"
23#include "kernel.h"
24#include "thread.h"
25#include "debug.h"
26#include "system.h"
27#include "fmradio.h"
28
29#if CONFIG_TUNER
30
31/* Signals:
32 DI (Data In) - PB0 (doubles as data pin for the LCD)
33 CL (Clock) - PB1 (doubles as clock for the LCD)
34 CE (Chip Enable) - PB3 (also chip select for the LCD, but active low)
35 DO (Data Out) - PB4
36*/
37
38/* cute little functions */
39#define CE_LO and_b(~0x08, PBDRL_ADDR)
40#define CE_HI or_b(0x08, PBDRL_ADDR)
41#define CL_LO and_b(~0x02, PBDRL_ADDR)
42#define CL_HI or_b(0x02, PBDRL_ADDR)
43#define DO (PBDR & 0x10)
44#define DI_LO and_b(~0x01, PBDRL_ADDR)
45#define DI_HI or_b(0x01, PBDRL_ADDR)
46
47#define START or_b((0x08 | 0x02), PBDRL_ADDR)
48
49/* delay loop */
50#define DELAY do { int _x; for(_x=0;_x<10;_x++);} while (0)
51
52
53int fmradio_read(int addr)
54{
55 int i;
56 int data = 0;
57
58 START;
59
60 /* First address bit */
61 CL_LO;
62 if(addr & 2)
63 DI_HI;
64 else
65 DI_LO;
66 DELAY;
67 CL_HI;
68 DELAY;
69
70 /* Second address bit */
71 CL_LO;
72 if(addr & 1)
73 DI_HI;
74 else
75 DI_LO;
76 DELAY;
77 CL_HI;
78 DELAY;
79
80 for(i = 0; i < 21;i++)
81 {
82 CL_LO;
83 DELAY;
84 data <<= 1;
85 data |= (DO)?1:0;
86 CL_HI;
87 DELAY;
88 }
89
90 CE_LO;
91
92 return data;
93}
94
95void fmradio_set(int addr, int data)
96{
97 int i;
98
99 /* Include the address in the data */
100 data |= addr << 21;
101
102 START;
103
104 for(i = 0; i < 23;i++)
105 {
106 CL_LO;
107 DELAY;
108 if(data & (1 << 22))
109 DI_HI;
110 else
111 DI_LO;
112
113 data <<= 1;
114 CL_HI;
115 DELAY;
116 }
117
118 CE_LO;
119}
120
121#endif
diff --git a/firmware/drivers/rtc/rtc_m41st84w.c b/firmware/drivers/rtc/rtc_m41st84w.c
deleted file mode 100644
index 621e650f68..0000000000
--- a/firmware/drivers/rtc/rtc_m41st84w.c
+++ /dev/null
@@ -1,296 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Linus Nielsen Feltzing, Uwe Freese, Laurent Baum
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "config.h"
22#include "i2c.h"
23#include "rtc.h"
24#include "kernel.h"
25#include "system.h"
26#include "timefuncs.h"
27
28#define RTC_ADR 0xd0
29#define RTC_DEV_WRITE (RTC_ADR | 0x00)
30#define RTC_DEV_READ (RTC_ADR | 0x01)
31
32void rtc_init(void)
33{
34 unsigned char data;
35
36#ifdef HAVE_RTC_ALARM
37 /* Check + save alarm bit first, before the power thread starts watching */
38 rtc_check_alarm_started(false);
39#endif
40
41 /* Clear the Stop bit if it is set */
42 data = rtc_read(0x01);
43 if(data & 0x80)
44 rtc_write(0x01, 0x00);
45
46 /* Clear the HT bit if it is set */
47 data = rtc_read(0x0c);
48
49 if(data & 0x40)
50 {
51 data &= ~0x40;
52 rtc_write(0x0c,data);
53 }
54
55#ifdef HAVE_RTC_ALARM
56
57 /* Clear Trec bit, write-protecting the RTC for 200ms when shutting off */
58 /* without this, the alarm won't work! */
59
60 data = rtc_read(0x04);
61 if (data & 0x80)
62 {
63 data &= ~0x80;
64 rtc_write(0x04, data);
65 }
66
67 /* Also, make sure that the OUT bit in register 8 is 1,
68 otherwise the player can't be turned off. */
69 rtc_write(8, rtc_read(8) | 0x80);
70
71#endif
72}
73
74#ifdef HAVE_RTC_ALARM
75
76/* check whether the unit has been started by the RTC alarm function */
77/* (check for AF, which => started using wakeup alarm) */
78bool rtc_check_alarm_started(bool release_alarm)
79{
80 static bool alarm_state, run_before;
81 bool rc;
82
83 if (run_before) {
84 rc = alarm_state;
85 alarm_state &= ~release_alarm;
86 } else {
87 /* This call resets AF, so we store the state for later recall */
88 rc = alarm_state = rtc_check_alarm_flag();
89 run_before = true;
90 }
91
92 return rc;
93}
94/*
95 * Checks the AL register. This call resets AL once read.
96 *
97 * We're only interested if ABE is set. AL is still raised regardless
98 * even if the unit is off when the alarm occurs.
99 */
100bool rtc_check_alarm_flag(void)
101{
102 return ( ( (rtc_read(0x0f) & 0x40) != 0) &&
103 (rtc_read(0x0a) & 0x20) );
104}
105
106/* set alarm time registers to the given time (repeat once per day) */
107void rtc_set_alarm(int h, int m)
108{
109 unsigned char data;
110
111 /* for daily alarm, RPT5=RPT4=on, RPT1=RPT2=RPT3=off */
112
113 rtc_write(0x0e, 0x00); /* seconds 0 and RTP1 */
114 rtc_write(0x0d, DEC2BCD(m)); /* minutes and RPT2 */
115 rtc_write(0x0c, DEC2BCD(h)); /* hour and RPT3 */
116 rtc_write(0x0b, 0xc1); /* set date 01 and RPT4 and RTP5 */
117
118 /* set month to 1, if it's invalid, the rtc does an alarm every second instead */
119 data = rtc_read(0x0a);
120 data &= 0xe0;
121 data |= 0x01;
122 rtc_write(0x0a, data);
123}
124
125/* read out the current alarm time */
126void rtc_get_alarm(int *h, int *m)
127{
128 unsigned char data;
129
130 data = rtc_read(0x0c);
131 *h = BCD2DEC(data & 0x3f);
132
133 data = rtc_read(0x0d);
134 *m = BCD2DEC(data & 0x7f);
135}
136
137/* turn alarm on or off by setting the alarm flag enable */
138/* the alarm is automatically disabled when the RTC gets Vcc power at startup */
139/* avoid that an alarm occurs when the device is on because this locks the ON key forever */
140void rtc_enable_alarm(bool enable)
141{
142 unsigned char data = rtc_read(0x0a);
143 if (enable)
144 {
145 data |= 0xa0; /* turn bit d7=AFE and d5=ABE on */
146 }
147 else
148 data &= 0x5f; /* turn bit d7=AFE and d5=ABE off */
149 rtc_write(0x0a, data);
150
151 /* check if alarm flag AF is off (as it should be) */
152 /* in some cases enabling the alarm results in an activated AF flag */
153 /* this should not happen, but it does */
154 /* if you know why, tell me! */
155 /* for now, we try again forever in this case */
156 while (rtc_check_alarm_flag()) /* on */
157 {
158 data &= 0x5f; /* turn bit d7=AFE and d5=ABE off */
159 rtc_write(0x0a, data);
160 sleep(HZ / 10);
161 rtc_check_alarm_flag();
162 data |= 0xa0; /* turn bit d7=AFE and d5=ABE on */
163 rtc_write(0x0a, data);
164 }
165}
166
167#endif /* HAVE_RTC_ALARM */
168
169int rtc_write(unsigned char address, unsigned char value)
170{
171 int ret = 0;
172 unsigned char buf[2];
173
174 i2c_begin();
175
176 buf[0] = address;
177 buf[1] = value;
178
179 /* send run command */
180 if (i2c_write(RTC_DEV_WRITE,buf,2))
181 {
182 ret = -1;
183 }
184
185 i2c_end();
186 return ret;
187}
188
189int rtc_read(unsigned char address)
190{
191 int value = -1;
192 unsigned char buf[1];
193
194 i2c_begin();
195
196 buf[0] = address;
197
198 /* send read command */
199 if (i2c_write(RTC_DEV_READ,buf,1) >= 0)
200 {
201 i2c_start();
202 i2c_outb(RTC_DEV_READ);
203 if (i2c_getack())
204 {
205 value = i2c_inb(1);
206 }
207 }
208
209 i2c_stop();
210
211 i2c_end();
212 return value;
213}
214
215int rtc_read_multiple(unsigned char address, unsigned char *buf, int numbytes)
216{
217 int ret = 0;
218 unsigned char obuf[1];
219 int i;
220
221 i2c_begin();
222
223 obuf[0] = address;
224
225 /* send read command */
226 if (i2c_write(RTC_DEV_READ, obuf, 1) >= 0)
227 {
228 i2c_start();
229 i2c_outb(RTC_DEV_READ);
230 if (i2c_getack())
231 {
232 for(i = 0;i < numbytes-1;i++)
233 buf[i] = i2c_inb(0);
234
235 buf[i] = i2c_inb(1);
236 }
237 else
238 {
239 ret = -1;
240 }
241 }
242
243 i2c_stop();
244
245 i2c_end();
246 return ret;
247}
248
249int rtc_read_datetime(struct tm *tm)
250{
251 int rc;
252 unsigned char buf[7];
253
254 rc = rtc_read_multiple(1, buf, sizeof(buf));
255
256 /* convert from bcd, avoid getting extra bits */
257 tm->tm_sec = BCD2DEC(buf[0] & 0x7f);
258 tm->tm_min = BCD2DEC(buf[1] & 0x7f);
259 tm->tm_hour = BCD2DEC(buf[2] & 0x3f);
260 tm->tm_mday = BCD2DEC(buf[4] & 0x3f);
261 tm->tm_mon = BCD2DEC(buf[5] & 0x1f) - 1;
262 tm->tm_year = BCD2DEC(buf[6]) + 100;
263 tm->tm_yday = 0; /* Not implemented for now */
264
265 set_day_of_week(tm);
266
267 return rc;
268}
269
270int rtc_write_datetime(const struct tm *tm)
271{
272 unsigned int i;
273 int rc = 0;
274 unsigned char buf[7];
275
276 buf[0] = tm->tm_sec;
277 buf[1] = tm->tm_min;
278 buf[2] = tm->tm_hour;
279 buf[3] = tm->tm_wday;
280 buf[4] = tm->tm_mday;
281 buf[5] = tm->tm_mon + 1;
282 buf[6] = tm->tm_year - 100;
283
284 /* Adjust weekday */
285 if (buf[3] == 0)
286 buf[3] = 7;
287
288 for (i = 0; i < sizeof(buf) ;i++)
289 {
290 rc |= rtc_write(i + 1, DEC2BCD(buf[i]));
291 }
292 rc |= rtc_write(8, 0x80); /* Out=1, calibration = 0 */
293
294 return rc;
295}
296
diff --git a/firmware/drivers/tuner/s1a0903x01.c b/firmware/drivers/tuner/s1a0903x01.c
deleted file mode 100644
index 91d1319fb5..0000000000
--- a/firmware/drivers/tuner/s1a0903x01.c
+++ /dev/null
@@ -1,179 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 * Tuner "middleware" for Samsung S1A0903X01 chip
10 *
11 * Copyright (C) 2003 Linus Nielsen Feltzing
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22
23#include <stdbool.h>
24#include <stdlib.h>
25#include "config.h"
26#include "kernel.h"
27#include "tuner.h" /* tuner abstraction interface */
28#include "fmradio.h" /* physical interface driver */
29#include "sound.h"
30#include "mas35xx.h"
31#include "power.h"
32
33#define DEFAULT_IN1 0x100003 /* Mute */
34#define DEFAULT_IN2 0x140884 /* 5kHz, 7.2MHz crystal */
35#define PLL_FREQ_STEP 10000
36
37static int fm_in1;
38static int fm_in2;
39static int fm_present = -1; /* unknown */
40
41/* tuner abstraction layer: set something to the tuner */
42int s1a0903x01_set(int setting, int value)
43{
44 int val = 1;
45
46 switch(setting)
47 {
48 case RADIO_SLEEP:
49 if (!value)
50 {
51 tuner_power(true);
52 /* wakeup: just unit */
53 fm_in1 = DEFAULT_IN1;
54 fm_in2 = DEFAULT_IN2;
55 fmradio_set(1, fm_in1);
56 fmradio_set(2, fm_in2);
57 }
58 else
59 tuner_power(false);
60 /* else we have no sleep mode? */
61 break;
62
63 case RADIO_FREQUENCY:
64 {
65 int pll_cnt;
66#if CONFIG_CODEC == MAS3587F
67 /* Shift the MAS internal clock away for certain frequencies to
68 * avoid interference. */
69 int pitch = 1000;
70
71 /* 4th harmonic falls in the FM frequency range */
72 int if_freq = 4 * mas_get_pllfreq();
73
74 /* shift the mas harmonic >= 300 kHz away using the direction
75 * which needs less shifting. */
76 if (value < if_freq)
77 {
78 if (if_freq - value < 300000)
79 pitch = 1003 - (if_freq - value) / 100000;
80 }
81 else
82 {
83 if (value - if_freq < 300000)
84 pitch = 997 + (value - if_freq) / 100000;
85 }
86 sound_set_pitch(pitch);
87#endif
88 /* We add the standard Intermediate Frequency 10.7MHz
89 ** before calculating the divisor
90 ** The reference frequency is set to 50kHz, and the VCO
91 ** output is prescaled by 2.
92 */
93
94 pll_cnt = (value + 10700000) / (PLL_FREQ_STEP/2) / 2;
95
96 /* 0x100000 == FM mode
97 ** 0x000002 == Microprocessor controlled Mute
98 */
99 fm_in1 = (fm_in1 & 0xfff00007) | (pll_cnt << 3);
100 fmradio_set(1, fm_in1);
101 break;
102 }
103
104 case RADIO_SCAN_FREQUENCY:
105 /* Tune in and delay */
106 s1a0903x01_set(RADIO_FREQUENCY, value);
107 sleep(1);
108 /* Start IF measurement */
109 fm_in1 |= 4;
110 fmradio_set(1, fm_in1);
111 sleep(1);
112 val = s1a0903x01_get(RADIO_TUNED);
113 break;
114
115 case RADIO_MUTE:
116 fm_in1 = (fm_in1 & 0xfffffffe) | (value?1:0);
117 fmradio_set(1, fm_in1);
118 break;
119
120 case RADIO_FORCE_MONO:
121 fm_in2 = (fm_in2 & 0xfffffffb) | (value?0:4);
122 fmradio_set(2, fm_in2);
123 break;
124 /* NOTE: These were only zeroed when starting the tuner from OFF
125 but the default values already set them to 0. */
126#if 0
127 case S1A0903X01_IF_MEASUREMENT:
128 fm_in1 = (fm_in1 & 0xfffffffb) | (value?4:0);
129 fmradio_set(1, fm_in1);
130 break;
131
132 case S1A0903X01_SENSITIVITY:
133 fm_in2 = (fm_in2 & 0xffff9fff) | ((value & 3) << 13);
134 fmradio_set(2, fm_in2);
135 break;
136#endif
137 default:
138 val = -1;
139 }
140
141 return val;
142}
143
144/* tuner abstraction layer: read something from the tuner */
145int s1a0903x01_get(int setting)
146{
147 int val = -1;
148 switch(setting)
149 {
150 case RADIO_PRESENT:
151 if (fm_present == -1)
152 {
153#ifdef HAVE_TUNER_PWR_CTRL
154 bool fmstatus = tuner_power(true);
155#endif
156 /* 5kHz, 7.2MHz crystal, test mode 1 */
157 fmradio_set(2, 0x140885);
158 fm_present = (fmradio_read(0) == 0x140885);
159#ifdef HAVE_TUNER_PWR_CTRL
160 if (!fmstatus)
161 tuner_power(false);
162#endif
163 }
164
165 val = fm_present;
166 break;
167
168 case RADIO_TUNED:
169 val = fmradio_read(3);
170 val = abs(10700 - ((val & 0x7ffff) / 8)) < 50; /* convert to kHz */
171 break;
172
173 case RADIO_STEREO:
174 val = fmradio_read(3);
175 val = ((val & 0x100000) ? true : false);
176 break;
177 }
178 return val;
179}