Remove solved issue
[maemo-rb.git] / firmware / drivers / tuner / tea5767.c
blob3f3af68602fa5c2ad15f77951520e1dac222ac78
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 * Tuner "middleware" for Philips TEA5767 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 #if defined(PHILIPS_HDD1630) || defined(ONDA_VX747) || defined(ONDA_VX777) || defined(PHILIPS_HDD6330)
32 #define I2C_ADR 0x60
33 #else
34 #define I2C_ADR 0xC0
35 #endif
37 /* define RSSI range */
38 #define RSSI_MIN 10
39 #define RSSI_MAX 55
41 static bool tuner_present = true;
42 static unsigned char write_bytes[5] = { 0x00, 0x00, 0x00, 0x00, 0x00 };
44 static void tea5767_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 tea5767_set(int setting, int value)
54 switch(setting)
56 case RADIO_SLEEP:
57 /* init values */
58 write_bytes[0] |= (1<<7); /* mute */
59 #if CONFIG_TUNER_XTAL == 32768
60 /* 32.768kHz, soft mute, stereo noise cancelling */
61 write_bytes[3] |= (1<<4) | (1<<3) | (1<<1);
62 #else
63 /* soft mute, stereo noise cancelling */
64 write_bytes[3] |= (1<<3) | (1<<1);
65 #endif
66 /* sleep / standby mode */
67 tea5767_set_clear(3, (1<<6), value);
68 break;
70 case RADIO_FREQUENCY:
72 int n;
73 #if CONFIG_TUNER_XTAL == 32768
74 n = (4 * (value - 225000) + 16384) / 32768;
75 #else
76 n = (4 * (value - 225000)) / 50000;
77 #endif
78 write_bytes[0] = (write_bytes[0] & 0xC0) | (n >> 8);
79 write_bytes[1] = n;
81 break;
83 case RADIO_SCAN_FREQUENCY:
84 tea5767_set(RADIO_FREQUENCY, value);
85 sleep(HZ/30);
86 return tea5767_get(RADIO_TUNED);
88 case RADIO_MUTE:
89 tea5767_set_clear(0, 0x80, value);
90 break;
92 case RADIO_REGION:
94 const struct fm_region_data *rd = &fm_region_data[value];
95 int deemphasis = (rd->deemphasis == 75) ? 1 : 0;
96 int band = (rd->freq_min == 76000000) ? 1 : 0;
98 tea5767_set_clear(4, (1<<6), deemphasis);
99 tea5767_set_clear(3, (1<<5), band);
100 break;
102 case RADIO_FORCE_MONO:
103 tea5767_set_clear(2, 0x08, value);
104 break;
105 default:
106 return -1;
109 fmradio_i2c_write(I2C_ADR, write_bytes, sizeof(write_bytes));
110 return 1;
113 /* tuner abstraction layer: read something from the tuner */
114 int tea5767_get(int setting)
116 unsigned char read_bytes[5];
117 int val = -1; /* default for unsupported query */
119 fmradio_i2c_read(I2C_ADR, read_bytes, sizeof(read_bytes));
121 switch(setting)
123 case RADIO_PRESENT:
124 val = tuner_present;
125 break;
127 case RADIO_TUNED:
128 val = 0;
129 if (read_bytes[0] & 0x80) /* ready */
131 val = read_bytes[2] & 0x7F; /* IF counter */
132 val = (abs(val - 0x36) < 2); /* close match */
134 break;
136 case RADIO_STEREO:
137 val = read_bytes[2] >> 7;
138 break;
140 case RADIO_RSSI:
141 val = 10 + 3*(read_bytes[3] >> 4);
142 break;
144 case RADIO_RSSI_MIN:
145 val = RSSI_MIN;
146 break;
148 case RADIO_RSSI_MAX:
149 val = RSSI_MAX;
150 break;
153 return val;
156 void tea5767_init(void)
158 /* save binsize by only detecting presence for targets where it may be absent */
159 #if defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330)
160 unsigned char buf[5];
161 unsigned char chipid;
163 /* init chipid register with 0xFF in case fmradio_i2c_read fails silently */
164 buf[3] = 0xFF;
165 if (fmradio_i2c_read(I2C_ADR, buf, sizeof(buf)) < 0) {
166 /* no i2c device detected */
167 tuner_present = false;
168 } else {
169 /* check chip id */
170 chipid = buf[3] & 0x0F;
171 tuner_present = (chipid == 0);
173 #endif
176 void tea5767_dbg_info(struct tea5767_dbg_info *info)
178 fmradio_i2c_read(I2C_ADR, info->read_regs, 5);
179 memcpy(info->write_regs, write_bytes, 5);