Manual: Small English improvement
[maemo-rb.git] / firmware / drivers / tuner / tea5760uk.c
blobc1dff598b32df99ca82f13bf9b4cd591a55a2f35
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 * Tuner "middleware" for Philips TEA5760UK chip
11 * Copyright (C) 2004 Jörg Hohensohn
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.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ****************************************************************************/
22 #include "config.h"
23 #include <stdbool.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include "kernel.h"
27 #include "tuner.h" /* tuner abstraction interface */
28 #include "fmradio.h"
29 #include "fmradio_i2c.h" /* physical interface driver */
31 #define I2C_ADR 0x22
33 /* define RSSI range */
34 #define RSSI_MIN 4
35 #define RSSI_MAX 46
37 static bool tuner_present = false;
38 static unsigned char write_bytes[7] = {
39 0x00, /* INTREG LSB */
40 0x80, /* FRQSET MSB */
41 0x00, /* FRQSET LSB */
42 0x08, /* TNCTRL MSB */
43 0xD2, /* TNCTRL LSB */
44 0x00, /* TESTREG MSB */
45 0x40 /* TESTREG LSB */
48 static void tea5760_set_clear(int byte, unsigned char bits, int set)
50 write_bytes[byte] &= ~bits;
51 if (set)
52 write_bytes[byte] |= bits;
55 /* tuner abstraction layer: set something to the tuner */
56 int tea5760_set(int setting, int value)
58 switch(setting)
60 case RADIO_SLEEP:
61 if (value) {
62 /* sleep / standby mode */
63 tea5760_set_clear(3, (1<<6), 0);
65 else {
66 /* active mode */
67 tea5760_set_clear(3, (1<<6), 1);
68 /* disable hard mute */
69 tea5760_set_clear(4, (1<<7), 0);
71 break;
73 case RADIO_FREQUENCY:
75 int n;
77 /* low side injection */
78 tea5760_set_clear(4, (1<<4), 0);
79 n = (4 * (value - 225000) + 16384) / 32768;
81 /* set frequency in preset mode */
82 write_bytes[1] = (n >> 8) & 0x3F;
83 write_bytes[2] = n;
85 break;
87 case RADIO_SCAN_FREQUENCY:
88 tea5760_set(RADIO_FREQUENCY, value);
89 sleep(40*HZ/1000);
90 return tea5760_get(RADIO_TUNED);
92 case RADIO_MUTE:
93 tea5760_set_clear(3, (1<<2), value);
94 break;
96 case RADIO_REGION:
98 const struct fm_region_data *rd = &fm_region_data[value];
99 int band = (rd->freq_min == 76000000) ? 1 : 0;
100 int deemphasis = (rd->deemphasis == 50) ? 1 : 0;
102 tea5760_set_clear(3, (1<<5), band);
103 tea5760_set_clear(4, (1<<1), deemphasis);
105 break;
107 case RADIO_FORCE_MONO:
108 tea5760_set_clear(4, (1<<3), value);
109 break;
111 default:
112 return -1;
115 fmradio_i2c_write(I2C_ADR, write_bytes, sizeof(write_bytes));
116 return 1;
119 /* tuner abstraction layer: read something from the tuner */
120 int tea5760_get(int setting)
122 unsigned char read_bytes[16];
123 int val = -1; /* default for unsupported query */
125 fmradio_i2c_read(I2C_ADR, read_bytes, sizeof(read_bytes));
127 switch(setting)
129 case RADIO_PRESENT:
130 val = tuner_present ? 1 : 0;
131 break;
133 case RADIO_TUNED:
134 val = 0;
135 if (read_bytes[0] & (1<<4)) /* IF count correct */
137 val = read_bytes[8] >> 1; /* IF counter */
138 val = (abs(val - 0x36) < 2); /* close match */
140 break;
142 case RADIO_STEREO:
143 val = read_bytes[9] >> 2;
144 break;
146 case RADIO_RSSI:
147 val = (read_bytes[9] >> 4) & 0x0F;
148 val = 4 + (28 * val + 5) / 10;
149 break;
151 case RADIO_RSSI_MIN:
152 val = RSSI_MIN;
153 break;
155 case RADIO_RSSI_MAX:
156 val = RSSI_MAX;
157 break;
160 return val;
163 void tea5760_init(void)
165 unsigned char buf[16];
166 unsigned short manid, chipid;
168 /* read all registers */
169 fmradio_i2c_read(I2C_ADR, buf, sizeof(buf));
171 /* check device id */
172 manid = (buf[12] << 8) | buf[13];
173 chipid = (buf[14] << 8) | buf[15];
174 if ((manid == 0x202B) && (chipid == 0x5760))
176 tuner_present = true;
179 /* write initial values */
180 tea5760_set_clear(3, (1<<1), 1); /* soft mute on */
181 tea5760_set_clear(3, (1<<0), 1); /* stereo noise cancellation on */
182 fmradio_i2c_write(I2C_ADR, write_bytes, sizeof(write_bytes));
185 void tea5760_dbg_info(struct tea5760_dbg_info *info)
187 fmradio_i2c_read(I2C_ADR, info->read_regs, sizeof(info->read_regs));
188 memcpy(info->write_regs, write_bytes, sizeof(info->write_regs));