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 static bool tuner_present
= false;
34 static unsigned char write_bytes
[7] = {
35 0x00, /* INTREG LSB */
36 0x80, /* FRQSET MSB */
37 0x00, /* FRQSET LSB */
38 0x08, /* TNCTRL MSB */
39 0xD2, /* TNCTRL LSB */
40 0x00, /* TESTREG MSB */
41 0x40 /* TESTREG LSB */
44 static void tea5760_set_clear(int byte
, unsigned char bits
, int set
)
46 write_bytes
[byte
] &= ~bits
;
48 write_bytes
[byte
] |= bits
;
51 /* tuner abstraction layer: set something to the tuner */
52 int tea5760_set(int setting
, int value
)
58 /* sleep / standby mode */
59 tea5760_set_clear(3, (1<<6), 0);
63 tea5760_set_clear(3, (1<<6), 1);
64 /* disable hard mute */
65 tea5760_set_clear(4, (1<<7), 0);
73 /* low side injection */
74 tea5760_set_clear(4, (1<<4), 0);
75 n
= (4 * (value
- 225000) + 16384) / 32768;
77 /* set frequency in preset mode */
78 write_bytes
[1] = (n
>> 8) & 0x3F;
83 case RADIO_SCAN_FREQUENCY
:
84 tea5760_set(RADIO_FREQUENCY
, value
);
86 return tea5760_get(RADIO_TUNED
);
89 tea5760_set_clear(3, (1<<2), value
);
94 const struct fm_region_data
*rd
= &fm_region_data
[value
];
95 int band
= (rd
->freq_min
== 76000000) ? 1 : 0;
96 int deemphasis
= (rd
->deemphasis
== 50) ? 1 : 0;
98 tea5760_set_clear(3, (1<<5), band
);
99 tea5760_set_clear(4, (1<<1), deemphasis
);
103 case RADIO_FORCE_MONO
:
104 tea5760_set_clear(4, (1<<3), value
);
111 fmradio_i2c_write(I2C_ADR
, write_bytes
, sizeof(write_bytes
));
115 /* tuner abstraction layer: read something from the tuner */
116 int tea5760_get(int setting
)
118 unsigned char read_bytes
[16];
119 int val
= -1; /* default for unsupported query */
121 fmradio_i2c_read(I2C_ADR
, read_bytes
, sizeof(read_bytes
));
126 val
= tuner_present
? 1 : 0;
131 if (read_bytes
[0] & (1<<4)) /* IF count correct */
133 val
= read_bytes
[8] >> 1; /* IF counter */
134 val
= (abs(val
- 0x36) < 2); /* close match */
139 val
= read_bytes
[9] >> 2;
146 void tea5760_init(void)
148 unsigned char buf
[16];
149 unsigned short manid
, chipid
;
151 /* read all registers */
152 fmradio_i2c_read(I2C_ADR
, buf
, sizeof(buf
));
154 /* check device id */
155 manid
= (buf
[12] << 8) | buf
[13];
156 chipid
= (buf
[14] << 8) | buf
[15];
157 if ((manid
== 0x202B) && (chipid
== 0x5760))
159 tuner_present
= true;
162 /* write initial values */
163 tea5760_set_clear(3, (1<<1), 1); /* soft mute on */
164 tea5760_set_clear(3, (1<<0), 1); /* stereo noise cancellation on */
165 fmradio_i2c_write(I2C_ADR
, write_bytes
, sizeof(write_bytes
));
168 void tea5760_dbg_info(struct tea5760_dbg_info
*info
)
170 fmradio_i2c_read(I2C_ADR
, info
->read_regs
, sizeof(info
->read_regs
));
171 memcpy(info
->write_regs
, write_bytes
, sizeof(info
->write_regs
));