diff options
-rw-r--r-- | apps/keymaps/keymap-gigabeat-s.c | 18 | ||||
-rw-r--r-- | apps/recorder/radio.c | 6 | ||||
-rw-r--r-- | firmware/SOURCES | 2 | ||||
-rw-r--r-- | firmware/drivers/audio/wm8978.c | 12 | ||||
-rw-r--r-- | firmware/drivers/tuner/si4700.c | 151 | ||||
-rw-r--r-- | firmware/export/audio.h | 1 | ||||
-rw-r--r-- | firmware/export/config-gigabeat-s.h | 7 | ||||
-rw-r--r-- | firmware/export/si4700.h | 12 | ||||
-rw-r--r-- | firmware/export/wm8978.h | 3 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/audio-gigabeat-s.c | 56 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/fmradio-i2c-gigabeat-s.c | 49 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/power-imx31.c | 30 | ||||
-rw-r--r-- | firmware/tuner.c | 16 |
13 files changed, 354 insertions, 9 deletions
diff --git a/apps/keymaps/keymap-gigabeat-s.c b/apps/keymaps/keymap-gigabeat-s.c index a60fd2d8a1..b0cc87011f 100644 --- a/apps/keymaps/keymap-gigabeat-s.c +++ b/apps/keymaps/keymap-gigabeat-s.c | |||
@@ -276,6 +276,22 @@ static const struct button_mapping button_context_keyboard[] = { | |||
276 | LAST_ITEM_IN_LIST | 276 | LAST_ITEM_IN_LIST |
277 | }; /* button_context_keyboard */ | 277 | }; /* button_context_keyboard */ |
278 | 278 | ||
279 | static const struct button_mapping button_context_radio[] = { | ||
280 | { ACTION_FM_MENU, BUTTON_SELECT | BUTTON_REPEAT, BUTTON_NONE }, | ||
281 | { ACTION_FM_PRESET, BUTTON_SELECT | BUTTON_REL, BUTTON_SELECT }, | ||
282 | { ACTION_FM_STOP, BUTTON_POWER, BUTTON_NONE }, | ||
283 | { ACTION_FM_MODE, BUTTON_MENU, BUTTON_NONE }, | ||
284 | { ACTION_FM_EXIT, BUTTON_BACK, BUTTON_NONE }, | ||
285 | { ACTION_FM_PLAY, BUTTON_PLAY, BUTTON_NONE }, | ||
286 | { ACTION_SETTINGS_INC, BUTTON_VOL_UP, BUTTON_NONE }, | ||
287 | { ACTION_SETTINGS_INCREPEAT, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE }, | ||
288 | { ACTION_SETTINGS_DEC, BUTTON_VOL_DOWN, BUTTON_NONE }, | ||
289 | { ACTION_SETTINGS_DECREPEAT, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE }, | ||
290 | |||
291 | |||
292 | LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS) | ||
293 | }; | ||
294 | |||
279 | const struct button_mapping* get_context_mapping(int context) | 295 | const struct button_mapping* get_context_mapping(int context) |
280 | { | 296 | { |
281 | switch (context) | 297 | switch (context) |
@@ -319,6 +335,8 @@ const struct button_mapping* get_context_mapping(int context) | |||
319 | return button_context_pitchscreen; | 335 | return button_context_pitchscreen; |
320 | case CONTEXT_KEYBOARD: | 336 | case CONTEXT_KEYBOARD: |
321 | return button_context_keyboard; | 337 | return button_context_keyboard; |
338 | case CONTEXT_FM: | ||
339 | return button_context_radio; | ||
322 | } | 340 | } |
323 | return button_context_standard; | 341 | return button_context_standard; |
324 | } | 342 | } |
diff --git a/apps/recorder/radio.c b/apps/recorder/radio.c index 5f9fff8d64..dee38b5475 100644 --- a/apps/recorder/radio.c +++ b/apps/recorder/radio.c | |||
@@ -104,13 +104,17 @@ | |||
104 | #define FM_MODE | 104 | #define FM_MODE |
105 | #define FM_EXIT | 105 | #define FM_EXIT |
106 | #define FM_PLAY | 106 | #define FM_PLAY |
107 | |||
108 | #elif (CONFIG_KEYPAD == GIGABEAT_S_PAD) | ||
109 | #define FM_PRESET | ||
110 | #define FM_MODE | ||
107 | #endif | 111 | #endif |
108 | 112 | ||
109 | #define RADIO_SCAN_MODE 0 | 113 | #define RADIO_SCAN_MODE 0 |
110 | #define RADIO_PRESET_MODE 1 | 114 | #define RADIO_PRESET_MODE 1 |
111 | 115 | ||
112 | static int curr_preset = -1; | 116 | static int curr_preset = -1; |
113 | static int curr_freq; | 117 | static int curr_freq; /* current frequency in Hz */ |
114 | static int radio_mode = RADIO_SCAN_MODE; | 118 | static int radio_mode = RADIO_SCAN_MODE; |
115 | static int search_dir = 0; | 119 | static int search_dir = 0; |
116 | 120 | ||
diff --git a/firmware/SOURCES b/firmware/SOURCES index 68d10876c8..1fce6cfdb5 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES | |||
@@ -764,6 +764,8 @@ target/arm/imx31/gigabeat-s/usb-imx31.c | |||
764 | target/arm/imx31/gigabeat-s/wmcodec-imx31.c | 764 | target/arm/imx31/gigabeat-s/wmcodec-imx31.c |
765 | #ifndef BOOTLOADER | 765 | #ifndef BOOTLOADER |
766 | target/arm/imx31/gigabeat-s/pcm-imx31.c | 766 | target/arm/imx31/gigabeat-s/pcm-imx31.c |
767 | target/arm/imx31/gigabeat-s/audio-gigabeat-s.c | ||
768 | target/arm/imx31/gigabeat-s/fmradio-i2c-gigabeat-s.c | ||
767 | #endif | 769 | #endif |
768 | #endif /* SIMULATOR */ | 770 | #endif /* SIMULATOR */ |
769 | #endif /* GIGABEAT_S */ | 771 | #endif /* GIGABEAT_S */ |
diff --git a/firmware/drivers/audio/wm8978.c b/firmware/drivers/audio/wm8978.c index c2c19ca7be..6a7c974f43 100644 --- a/firmware/drivers/audio/wm8978.c +++ b/firmware/drivers/audio/wm8978.c | |||
@@ -144,12 +144,12 @@ static void wmc_write(unsigned int reg, unsigned int val) | |||
144 | wmcodec_write(reg, val); | 144 | wmcodec_write(reg, val); |
145 | } | 145 | } |
146 | 146 | ||
147 | static void wmc_set(unsigned int reg, unsigned int bits) | 147 | void wmc_set(unsigned int reg, unsigned int bits) |
148 | { | 148 | { |
149 | wmc_write(reg, wmc_regs[reg] | bits); | 149 | wmc_write(reg, wmc_regs[reg] | bits); |
150 | } | 150 | } |
151 | 151 | ||
152 | static void wmc_clear(unsigned int reg, unsigned int bits) | 152 | void wmc_clear(unsigned int reg, unsigned int bits) |
153 | { | 153 | { |
154 | wmc_write(reg, wmc_regs[reg] & ~bits); | 154 | wmc_write(reg, wmc_regs[reg] & ~bits); |
155 | } | 155 | } |
@@ -226,6 +226,14 @@ void audiohw_postinit(void) | |||
226 | wmc_write(WMC_AUDIO_INTERFACE, WMC_WL_16 | WMC_FMT_I2S); | 226 | wmc_write(WMC_AUDIO_INTERFACE, WMC_WL_16 | WMC_FMT_I2S); |
227 | wmc_write(WMC_DAC_CONTROL, WMC_DACOSR_128 | WMC_AMUTE); | 227 | wmc_write(WMC_DAC_CONTROL, WMC_DACOSR_128 | WMC_AMUTE); |
228 | 228 | ||
229 | wmc_set(WMC_INPUT_CTRL, WMC_R2_2INPPGA | WMC_L2_2INPPGA); | ||
230 | wmc_set(WMC_LEFT_INP_PGA_GAIN_CTRL, 0x3f); | ||
231 | wmc_set(WMC_RIGHT_INP_PGA_GAIN_CTRL, 0x3f); | ||
232 | wmc_set(WMC_LEFT_INP_PGA_GAIN_CTRL, 1<<8); | ||
233 | wmc_set(WMC_RIGHT_INP_PGA_GAIN_CTRL, 1<<8); | ||
234 | wmc_set(WMC_LEFT_ADC_BOOST_CTRL, (7<<3)); | ||
235 | wmc_set(WMC_RIGHT_ADC_BOOST_CTRL, (7<<3)); | ||
236 | |||
229 | /* Specific to HW clocking */ | 237 | /* Specific to HW clocking */ |
230 | wmc_write_masked(WMC_CLOCK_GEN_CTRL, WMC_BCLKDIV_4 | WMC_MS, | 238 | wmc_write_masked(WMC_CLOCK_GEN_CTRL, WMC_BCLKDIV_4 | WMC_MS, |
231 | WMC_BCLKDIV | WMC_MS | WMC_CLKSEL); | 239 | WMC_BCLKDIV | WMC_MS | WMC_CLKSEL); |
diff --git a/firmware/drivers/tuner/si4700.c b/firmware/drivers/tuner/si4700.c index 9233afae24..a55a8cfcc4 100644 --- a/firmware/drivers/tuner/si4700.c +++ b/firmware/drivers/tuner/si4700.c | |||
@@ -9,7 +9,7 @@ | |||
9 | * | 9 | * |
10 | * Tuner "middleware" for Silicon Labs SI4700 chip | 10 | * Tuner "middleware" for Silicon Labs SI4700 chip |
11 | * | 11 | * |
12 | * Copyright (C) 2008 ??? | 12 | * Copyright (C) 2008 Nils Wallménius |
13 | * | 13 | * |
14 | * This program is free software; you can redistribute it and/or | 14 | * This program is free software; you can redistribute it and/or |
15 | * modify it under the terms of the GNU General Public License | 15 | * modify it under the terms of the GNU General Public License |
@@ -29,19 +29,160 @@ | |||
29 | #include "fmradio.h" | 29 | #include "fmradio.h" |
30 | #include "fmradio_i2c.h" /* physical interface driver */ | 30 | #include "fmradio_i2c.h" /* physical interface driver */ |
31 | 31 | ||
32 | #define I2C_ADR 0x20 | ||
33 | |||
34 | /* I2C writes start at register 02h so the first two bytes are | ||
35 | 02h, next two 03h, etc. */ | ||
36 | static unsigned char write_bytes[8]; /* registers 02 - 05 */ | ||
37 | static bool tuner_present = false; | ||
38 | |||
39 | void si4700_init(void) | ||
40 | { | ||
41 | unsigned char read_bytes[32]; | ||
42 | tuner_power(true); | ||
43 | fmradio_i2c_read(I2C_ADR, read_bytes, sizeof(read_bytes)); | ||
44 | |||
45 | if ((read_bytes[12] << 8 | read_bytes[13]) == 0x1242) | ||
46 | { | ||
47 | tuner_present = true; | ||
48 | /* fill in the initial values in write_bytes */ | ||
49 | memcpy(&write_bytes[0], &read_bytes[16], sizeof(write_bytes)); | ||
50 | /* -6dB volume, keep everything else as default */ | ||
51 | write_bytes[7] = (write_bytes[7] & ~0xf) | 0xc; | ||
52 | } | ||
53 | |||
54 | tuner_power(false); | ||
55 | } | ||
56 | |||
57 | static void si4700_tune(void) | ||
58 | { | ||
59 | unsigned char read_bytes[1]; | ||
60 | |||
61 | write_bytes[2] |= (1 << 7); /* Set TUNE high to start tuning */ | ||
62 | fmradio_i2c_write(I2C_ADR, write_bytes, sizeof(write_bytes)); | ||
63 | |||
64 | do | ||
65 | { | ||
66 | sleep(HZ/50); | ||
67 | fmradio_i2c_read(I2C_ADR, read_bytes, 1); | ||
68 | } | ||
69 | while (!(read_bytes[0] & (1 << 6))); /* STC high == Seek/Tune complete */ | ||
70 | |||
71 | write_bytes[2] &= ~(1 << 7); /* Set TUNE low */ | ||
72 | fmradio_i2c_write(I2C_ADR, write_bytes, sizeof(write_bytes)); | ||
73 | } | ||
74 | |||
32 | /* tuner abstraction layer: set something to the tuner */ | 75 | /* tuner abstraction layer: set something to the tuner */ |
33 | int si4700_set(int setting, int value) | 76 | int si4700_set(int setting, int value) |
34 | { | 77 | { |
35 | (void)setting; | 78 | switch(setting) |
36 | (void)value; | 79 | { |
80 | case RADIO_SLEEP: | ||
81 | if (value) | ||
82 | { | ||
83 | write_bytes[1] = (1 | (1 << 6)); /* ENABLE high, DISABLE high */ | ||
84 | } | ||
85 | else | ||
86 | { | ||
87 | write_bytes[1] = 1; /* ENABLE high, DISABLE low */ | ||
88 | } | ||
89 | break; | ||
37 | 90 | ||
91 | case RADIO_FREQUENCY: | ||
92 | { | ||
93 | static const unsigned int spacings[3] = | ||
94 | { | ||
95 | 200000, 100000, 50000 | ||
96 | }; | ||
97 | unsigned int chan; | ||
98 | unsigned int spacing = spacings[(write_bytes[7] >> 4) & 3] ; | ||
99 | |||
100 | if (write_bytes[7] & (3 << 6)) /* check BAND */ | ||
101 | { | ||
102 | chan = (value - 76000000) / spacing; | ||
103 | } | ||
104 | else | ||
105 | { | ||
106 | chan = (value - 87500000) / spacing; | ||
107 | } | ||
108 | |||
109 | write_bytes[2] = (write_bytes[2] & ~3) | ((chan & (3 << 8)) >> 8); | ||
110 | write_bytes[3] = (chan & 0xff); | ||
111 | fmradio_i2c_write(I2C_ADR, write_bytes, sizeof(write_bytes)); | ||
112 | si4700_tune(); | ||
113 | return 1; | ||
114 | } | ||
115 | |||
116 | case RADIO_SCAN_FREQUENCY: | ||
117 | si4700_set(RADIO_FREQUENCY, value); | ||
118 | return 1; | ||
119 | |||
120 | case RADIO_MUTE: | ||
121 | if (value) | ||
122 | { | ||
123 | /* mute */ | ||
124 | write_bytes[0] &= ~(1 << 6); | ||
125 | } | ||
126 | else | ||
127 | { | ||
128 | /* unmute */ | ||
129 | write_bytes[0] |= (1 << 6); | ||
130 | } | ||
131 | break; | ||
132 | |||
133 | case RADIO_REGION: | ||
134 | { | ||
135 | const struct si4700_region_data *rd = | ||
136 | &si4700_region_data[value]; | ||
137 | |||
138 | write_bytes[4] = ((write_bytes[4] & ~(1 << 3)) | (rd->deemphasis << 3)); | ||
139 | write_bytes[7] = ((write_bytes[7] & ~(3 << 6)) | (rd->band << 6)); | ||
140 | write_bytes[7] = ((write_bytes[7] & ~(3 << 4)) | (rd->spacing << 4)); | ||
141 | break; | ||
142 | } | ||
143 | |||
144 | case RADIO_FORCE_MONO: | ||
145 | if (value) | ||
146 | { | ||
147 | write_bytes[0] |= (1 << 5); | ||
148 | } | ||
149 | else | ||
150 | { | ||
151 | write_bytes[0] &= ~(1 << 5); | ||
152 | } | ||
153 | break; | ||
154 | |||
155 | default: | ||
156 | return -1; | ||
157 | } | ||
158 | |||
159 | fmradio_i2c_write(I2C_ADR, write_bytes, sizeof(write_bytes)); | ||
38 | return 1; | 160 | return 1; |
39 | } | 161 | } |
40 | 162 | ||
41 | /* tuner abstraction layer: read something from the tuner */ | 163 | /* tuner abstraction layer: read something from the tuner */ |
42 | int si4700_get(int setting) | 164 | int si4700_get(int setting) |
43 | { | 165 | { |
44 | (void)setting; | 166 | /* I2C reads start with register 0xA */ |
167 | unsigned char read_bytes[1]; | ||
168 | int val = -1; /* default for unsupported query */ | ||
169 | |||
170 | switch(setting) | ||
171 | { | ||
172 | case RADIO_PRESENT: | ||
173 | val = tuner_present ? 1 : 0; | ||
174 | break; | ||
45 | 175 | ||
46 | return -1; | 176 | case RADIO_TUNED: |
177 | val = 1; | ||
178 | break; | ||
179 | |||
180 | case RADIO_STEREO: | ||
181 | fmradio_i2c_read(I2C_ADR, read_bytes, sizeof(read_bytes)); | ||
182 | val = (read_bytes[0] & 1); /* ST high == Stereo */ | ||
183 | break; | ||
184 | } | ||
185 | |||
186 | return val; | ||
47 | } | 187 | } |
188 | |||
diff --git a/firmware/export/audio.h b/firmware/export/audio.h index 661247df2f..4f9ef1a4e1 100644 --- a/firmware/export/audio.h +++ b/firmware/export/audio.h | |||
@@ -23,6 +23,7 @@ | |||
23 | 23 | ||
24 | #include <stdbool.h> | 24 | #include <stdbool.h> |
25 | #include <sys/types.h> | 25 | #include <sys/types.h> |
26 | #include "config.h" | ||
26 | /* These must always be included with audio.h for this to compile under | 27 | /* These must always be included with audio.h for this to compile under |
27 | cetain conditions. Do it here or else spread the complication around to | 28 | cetain conditions. Do it here or else spread the complication around to |
28 | many files. */ | 29 | many files. */ |
diff --git a/firmware/export/config-gigabeat-s.h b/firmware/export/config-gigabeat-s.h index 72b1cb76a8..c893061d0d 100644 --- a/firmware/export/config-gigabeat-s.h +++ b/firmware/export/config-gigabeat-s.h | |||
@@ -69,9 +69,14 @@ | |||
69 | /* The number of bytes reserved for loadable plugins */ | 69 | /* The number of bytes reserved for loadable plugins */ |
70 | #define PLUGIN_BUFFER_SIZE 0x80000 | 70 | #define PLUGIN_BUFFER_SIZE 0x80000 |
71 | 71 | ||
72 | /* Define this if you have a SI4700 fm radio tuner */ | ||
73 | #define CONFIG_TUNER SI4700 | ||
74 | |||
72 | /* Define this if you have the WM8978 audio codec */ | 75 | /* Define this if you have the WM8978 audio codec */ |
73 | #define HAVE_WM8978 | 76 | #define HAVE_WM8978 |
74 | 77 | ||
78 | #define INPUT_SRC_CAPS SRC_CAP_FMRADIO | ||
79 | |||
75 | #define HW_SAMPR_CAPS (SAMPR_CAP_48 | SAMPR_CAP_44 | SAMPR_CAP_32 | \ | 80 | #define HW_SAMPR_CAPS (SAMPR_CAP_48 | SAMPR_CAP_44 | SAMPR_CAP_32 | \ |
76 | SAMPR_CAP_24 | SAMPR_CAP_22 | SAMPR_CAP_16 | \ | 81 | SAMPR_CAP_24 | SAMPR_CAP_22 | SAMPR_CAP_16 | \ |
77 | SAMPR_CAP_12 | SAMPR_CAP_11 | SAMPR_CAP_8) | 82 | SAMPR_CAP_12 | SAMPR_CAP_11 | SAMPR_CAP_8) |
@@ -114,7 +119,7 @@ | |||
114 | 119 | ||
115 | /* Define the bitmask of modules used */ | 120 | /* Define the bitmask of modules used */ |
116 | #define SPI_MODULE_MASK (USE_CSPI2_MODULE) | 121 | #define SPI_MODULE_MASK (USE_CSPI2_MODULE) |
117 | #define I2C_MODULE_MASK (USE_I2C1_MODULE) | 122 | #define I2C_MODULE_MASK (USE_I2C1_MODULE | USE_I2C2_MODULE) |
118 | #define GPIO_EVENT_MASK (USE_GPIO1_EVENTS) | 123 | #define GPIO_EVENT_MASK (USE_GPIO1_EVENTS) |
119 | 124 | ||
120 | /* Define this if target has an additional number of threads specific to it */ | 125 | /* Define this if target has an additional number of threads specific to it */ |
diff --git a/firmware/export/si4700.h b/firmware/export/si4700.h index a740ae03ab..5b8001f753 100644 --- a/firmware/export/si4700.h +++ b/firmware/export/si4700.h | |||
@@ -25,6 +25,18 @@ | |||
25 | #ifndef _SI4700_H_ | 25 | #ifndef _SI4700_H_ |
26 | #define _SI4700_H_ | 26 | #define _SI4700_H_ |
27 | 27 | ||
28 | #define HAVE_RADIO_REGION | ||
29 | |||
30 | struct si4700_region_data | ||
31 | { | ||
32 | unsigned char deemphasis; /* 0: 50us, 1: 75us */ | ||
33 | unsigned char band; /* 0: us/europe, 1: japan */ | ||
34 | unsigned char spacing; /* 0: us/australia (200kHz), 1: europe/japan (100kHz), 2: (50kHz) */ | ||
35 | } __attribute__((packed)); | ||
36 | |||
37 | extern const struct si4700_region_data si4700_region_data[TUNER_NUM_REGIONS]; | ||
38 | |||
39 | void si4700_init(void); | ||
28 | int si4700_set(int setting, int value); | 40 | int si4700_set(int setting, int value); |
29 | int si4700_get(int setting); | 41 | int si4700_get(int setting); |
30 | 42 | ||
diff --git a/firmware/export/wm8978.h b/firmware/export/wm8978.h index f4ed46a6e2..9c54ae354d 100644 --- a/firmware/export/wm8978.h +++ b/firmware/export/wm8978.h | |||
@@ -30,6 +30,9 @@ int tenthdb2master(int db); | |||
30 | void audiohw_set_headphone_vol(int vol_l, int vol_r); | 30 | void audiohw_set_headphone_vol(int vol_l, int vol_r); |
31 | void audiohw_set_frequency(int sampling_control); | 31 | void audiohw_set_frequency(int sampling_control); |
32 | 32 | ||
33 | void wmc_set(unsigned int reg, unsigned int bits); | ||
34 | void wmc_clear(unsigned int reg, unsigned int bits); | ||
35 | |||
33 | #define WMC_I2C_ADDR 0x34 | 36 | #define WMC_I2C_ADDR 0x34 |
34 | 37 | ||
35 | /* Registers */ | 38 | /* Registers */ |
diff --git a/firmware/target/arm/imx31/gigabeat-s/audio-gigabeat-s.c b/firmware/target/arm/imx31/gigabeat-s/audio-gigabeat-s.c new file mode 100644 index 0000000000..6dd90bfdb7 --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/audio-gigabeat-s.c | |||
@@ -0,0 +1,56 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2008 by Nils Wallménius | ||
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 "wm8978.h" | ||
22 | #include "audio.h" | ||
23 | |||
24 | void audio_set_output_source(int source) | ||
25 | { | ||
26 | (void)source; /* TODO */ | ||
27 | } | ||
28 | |||
29 | void audio_input_mux(int source, unsigned int flags) | ||
30 | { | ||
31 | (void)flags; | ||
32 | switch (source) | ||
33 | { | ||
34 | case AUDIO_SRC_PLAYBACK: | ||
35 | /* deselect bypass patths and set volume to -15dB */ | ||
36 | wmc_clear(WMC_LEFT_MIXER_CTRL, (WMC_BYPL2LMIX) | (7<<2)); | ||
37 | wmc_clear(WMC_RIGHT_MIXER_CTRL, (WMC_BYPR2RMIX) | (7<<2)); | ||
38 | /* disable L2/R2 inputs and boost stage */ | ||
39 | wmc_clear(WMC_POWER_MANAGEMENT2, | ||
40 | WMC_INPPGAENR | WMC_INPPGAENL | WMC_BOOSTENL | WMC_BOOSTENR); | ||
41 | break; | ||
42 | |||
43 | case AUDIO_SRC_FMRADIO: | ||
44 | /* enable L2/R2 inputs and boost stage */ | ||
45 | wmc_set(WMC_POWER_MANAGEMENT2, | ||
46 | WMC_INPPGAENR | WMC_INPPGAENL | WMC_BOOSTENL | WMC_BOOSTENR); | ||
47 | /* select bypass patths and set volume to 0dB */ | ||
48 | wmc_set(WMC_LEFT_MIXER_CTRL, (WMC_BYPL2LMIX) | (5<<2)); | ||
49 | wmc_set(WMC_RIGHT_MIXER_CTRL, (WMC_BYPR2RMIX) | (5<<2)); | ||
50 | break; | ||
51 | |||
52 | default: | ||
53 | source = AUDIO_SRC_PLAYBACK; | ||
54 | } | ||
55 | } | ||
56 | |||
diff --git a/firmware/target/arm/imx31/gigabeat-s/fmradio-i2c-gigabeat-s.c b/firmware/target/arm/imx31/gigabeat-s/fmradio-i2c-gigabeat-s.c new file mode 100644 index 0000000000..5e5c4853dd --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/fmradio-i2c-gigabeat-s.c | |||
@@ -0,0 +1,49 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * Physical interface of the SI4700 in the Gigabeat S | ||
10 | * | ||
11 | * Copyright (C) 2008 by Nils Wallménius | ||
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 | #include "config.h" | ||
23 | #include "system.h" | ||
24 | #include "i2c-imx31.h" | ||
25 | #include "fmradio_i2c.h" | ||
26 | |||
27 | struct i2c_node si4700_i2c_node = | ||
28 | { | ||
29 | .num = I2C2_NUM, | ||
30 | .ifdr = I2C_IFDR_DIV192, /* 66MHz/.4MHz = 165, closest = 192 = 343750Hz */ | ||
31 | /* Just hard-code for now - scaling may require | ||
32 | * updating */ | ||
33 | .addr = (0x20), | ||
34 | }; | ||
35 | |||
36 | int fmradio_i2c_write(unsigned char address, const unsigned char* buf, int count) | ||
37 | { | ||
38 | (void)address; | ||
39 | i2c_write(&si4700_i2c_node, buf, count); | ||
40 | return 0; | ||
41 | } | ||
42 | |||
43 | int fmradio_i2c_read(unsigned char address, unsigned char* buf, int count) | ||
44 | { | ||
45 | (void)address; | ||
46 | i2c_read(&si4700_i2c_node, -1, buf, count); | ||
47 | return 0; | ||
48 | } | ||
49 | |||
diff --git a/firmware/target/arm/imx31/gigabeat-s/power-imx31.c b/firmware/target/arm/imx31/gigabeat-s/power-imx31.c index de7f5800e6..07e6462bfb 100644 --- a/firmware/target/arm/imx31/gigabeat-s/power-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/power-imx31.c | |||
@@ -26,6 +26,9 @@ | |||
26 | #include "backlight-target.h" | 26 | #include "backlight-target.h" |
27 | #include "avic-imx31.h" | 27 | #include "avic-imx31.h" |
28 | #include "mc13783.h" | 28 | #include "mc13783.h" |
29 | #include "i2c-imx31.h" | ||
30 | |||
31 | extern struct i2c_node si4700_i2c_node; | ||
29 | 32 | ||
30 | static bool charger_detect = false; | 33 | static bool charger_detect = false; |
31 | 34 | ||
@@ -79,6 +82,33 @@ bool ide_powered(void) | |||
79 | return (GPIO3_DR & (1 << 5)) != 0; | 82 | return (GPIO3_DR & (1 << 5)) != 0; |
80 | } | 83 | } |
81 | 84 | ||
85 | #if CONFIG_TUNER | ||
86 | bool tuner_power(bool status) | ||
87 | { | ||
88 | if (status) | ||
89 | { | ||
90 | /* the si4700 is the only thing connected to i2c2 so | ||
91 | we can diable the i2c module when not in use */ | ||
92 | i2c_enable_node(&si4700_i2c_node, true); | ||
93 | /* enable the fm chip */ | ||
94 | imx31_regmod32(&GPIO1_DR, (1 << 26), (1 << 26)); | ||
95 | /* enable CLK32KMCU clock */ | ||
96 | mc13783_set(MC13783_POWER_CONTROL0, MC13783_CLK32KMCUEN); | ||
97 | } | ||
98 | else | ||
99 | { | ||
100 | /* the si4700 is the only thing connected to i2c2 so | ||
101 | we can diable the i2c module when not in use */ | ||
102 | i2c_enable_node(&si4700_i2c_node, false); | ||
103 | /* disable the fm chip */ | ||
104 | imx31_regmod32(&GPIO1_DR, 0, (1 << 26)); | ||
105 | /* disable CLK32KMCU clock */ | ||
106 | mc13783_clear(MC13783_POWER_CONTROL0, MC13783_CLK32KMCUEN); | ||
107 | } | ||
108 | return true; | ||
109 | } | ||
110 | #endif /* #if CONFIG_TUNER */ | ||
111 | |||
82 | void power_off(void) | 112 | void power_off(void) |
83 | { | 113 | { |
84 | /* Cut backlight */ | 114 | /* Cut backlight */ |
diff --git a/firmware/tuner.c b/firmware/tuner.c index 6a7c1b4237..22cb981038 100644 --- a/firmware/tuner.c +++ b/firmware/tuner.c | |||
@@ -59,6 +59,16 @@ const struct tea5767_region_data tea5767_region_data[TUNER_NUM_REGIONS] = | |||
59 | }; | 59 | }; |
60 | #endif /* (CONFIG_TUNER & TEA5767) */ | 60 | #endif /* (CONFIG_TUNER & TEA5767) */ |
61 | 61 | ||
62 | #if (CONFIG_TUNER & SI4700) | ||
63 | const struct si4700_region_data si4700_region_data[TUNER_NUM_REGIONS] = | ||
64 | { | ||
65 | [REGION_EUROPE] = { 0, 0, 2 }, /* 50uS, US/Europe band, 50kHz spacing */ | ||
66 | [REGION_US_CANADA] = { 1, 0, 0 }, /* 75uS, US/Europe band, 200kHz spacing */ | ||
67 | [REGION_JAPAN] = { 0, 1, 1 }, /* 50uS, Japanese band, 100kHz spacing */ | ||
68 | [REGION_KOREA] = { 0, 0, 1 }, /* 50uS, US/Europe band, 100kHz spacing */ | ||
69 | }; | ||
70 | #endif /* (CONFIG_TUNER & SI4700) */ | ||
71 | |||
62 | #ifdef CONFIG_TUNER_MULTI | 72 | #ifdef CONFIG_TUNER_MULTI |
63 | int (*tuner_set)(int setting, int value); | 73 | int (*tuner_set)(int setting, int value); |
64 | int (*tuner_get)(int setting); | 74 | int (*tuner_get)(int setting); |
@@ -95,6 +105,12 @@ void tuner_init(void) | |||
95 | s1a0903x01_set, | 105 | s1a0903x01_set, |
96 | s1a0903x01_get) | 106 | s1a0903x01_get) |
97 | #endif | 107 | #endif |
108 | #if (CONFIG_TUNER & SI4700) | ||
109 | TUNER_TYPE_CASE(SI4700, | ||
110 | si4700_set, | ||
111 | si4700_get, | ||
112 | si4700_init()) | ||
113 | #endif | ||
98 | } | 114 | } |
99 | } | 115 | } |
100 | 116 | ||