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 tea5760_region_data
*rd
=
95 &tea5760_region_data
[value
];
97 tea5760_set_clear(4, (1<<1), rd
->deemphasis
);
98 tea5760_set_clear(3, (1<<5), rd
->band
);
102 case RADIO_FORCE_MONO
:
103 tea5760_set_clear(4, (1<<3), value
);
110 fmradio_i2c_write(I2C_ADR
, write_bytes
, sizeof(write_bytes
));
114 /* tuner abstraction layer: read something from the tuner */
115 int tea5760_get(int setting
)
117 unsigned char read_bytes
[16];
118 int val
= -1; /* default for unsupported query */
120 fmradio_i2c_read(I2C_ADR
, read_bytes
, sizeof(read_bytes
));
125 val
= tuner_present
? 1 : 0;
130 if (read_bytes
[0] & (1<<4)) /* IF count correct */
132 val
= read_bytes
[8] >> 1; /* IF counter */
133 val
= (abs(val
- 0x36) < 2); /* close match */
138 val
= read_bytes
[9] >> 2;
145 void tea5760_init(void)
147 unsigned char buf
[16];
148 unsigned short manid
, chipid
;
150 /* read all registers */
151 fmradio_i2c_read(I2C_ADR
, buf
, sizeof(buf
));
153 /* check device id */
154 manid
= (buf
[12] << 8) | buf
[13];
155 chipid
= (buf
[14] << 8) | buf
[15];
156 if ((manid
== 0x202B) && (chipid
== 0x5760))
158 tuner_present
= true;
161 /* write initial values */
162 tea5760_set_clear(3, (1<<1), 1); /* soft mute on */
163 tea5760_set_clear(3, (1<<0), 1); /* stereo noise cancellation on */
164 fmradio_i2c_write(I2C_ADR
, write_bytes
, sizeof(write_bytes
));
167 void tea5760_dbg_info(struct tea5760_dbg_info
*info
)
169 fmradio_i2c_read(I2C_ADR
, info
->read_regs
, sizeof(info
->read_regs
));
170 memcpy(info
->write_regs
, write_bytes
, sizeof(info
->write_regs
));