1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
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 ****************************************************************************/
27 #include "tuner.h" /* tuner abstraction interface */
29 #include "fmradio_i2c.h" /* physical interface driver */
33 /* define RSSI range */
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
;
52 write_bytes
[byte
] |= bits
;
55 /* tuner abstraction layer: set something to the tuner */
56 int tea5760_set(int setting
, int value
)
62 /* sleep / standby mode */
63 tea5760_set_clear(3, (1<<6), 0);
67 tea5760_set_clear(3, (1<<6), 1);
68 /* disable hard mute */
69 tea5760_set_clear(4, (1<<7), 0);
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;
87 case RADIO_SCAN_FREQUENCY
:
88 tea5760_set(RADIO_FREQUENCY
, value
);
90 return tea5760_get(RADIO_TUNED
);
93 tea5760_set_clear(3, (1<<2), value
);
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
);
107 case RADIO_FORCE_MONO
:
108 tea5760_set_clear(4, (1<<3), value
);
115 fmradio_i2c_write(I2C_ADR
, write_bytes
, sizeof(write_bytes
));
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
));
130 val
= tuner_present
? 1 : 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 */
143 val
= read_bytes
[9] >> 2;
147 val
= (read_bytes
[9] >> 4) & 0x0F;
148 val
= 4 + (28 * val
+ 5) / 10;
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
));