FM tuner region code cleanup - FS #11492 by me.
[maemo-rb.git] / firmware / drivers / tuner / tea5760uk.c
blob20234e28ed62f353dd44711271dc360956bd5d7d
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 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;
47 if (set)
48 write_bytes[byte] |= bits;
51 /* tuner abstraction layer: set something to the tuner */
52 int tea5760_set(int setting, int value)
54 switch(setting)
56 case RADIO_SLEEP:
57 if (value) {
58 /* sleep / standby mode */
59 tea5760_set_clear(3, (1<<6), 0);
61 else {
62 /* active mode */
63 tea5760_set_clear(3, (1<<6), 1);
64 /* disable hard mute */
65 tea5760_set_clear(4, (1<<7), 0);
67 break;
69 case RADIO_FREQUENCY:
71 int n;
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;
79 write_bytes[2] = n;
81 break;
83 case RADIO_SCAN_FREQUENCY:
84 tea5760_set(RADIO_FREQUENCY, value);
85 sleep(40*HZ/1000);
86 return tea5760_get(RADIO_TUNED);
88 case RADIO_MUTE:
89 tea5760_set_clear(3, (1<<2), value);
90 break;
92 case RADIO_REGION:
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);
101 break;
103 case RADIO_FORCE_MONO:
104 tea5760_set_clear(4, (1<<3), value);
105 break;
107 default:
108 return -1;
111 fmradio_i2c_write(I2C_ADR, write_bytes, sizeof(write_bytes));
112 return 1;
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));
123 switch(setting)
125 case RADIO_PRESENT:
126 val = tuner_present ? 1 : 0;
127 break;
129 case RADIO_TUNED:
130 val = 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 */
136 break;
138 case RADIO_STEREO:
139 val = read_bytes[9] >> 2;
140 break;
143 return val;
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));