3 Copyright (C) Manu Abraham (abraham.manu@gmail.com)
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include <linux/init.h>
21 #include <linux/kernel.h>
22 #include <linux/module.h>
23 #include <linux/slab.h>
25 #include "dvb_frontend.h"
28 struct tda665x_state
{
29 struct dvb_frontend
*fe
;
30 struct i2c_adapter
*i2c
;
31 const struct tda665x_config
*config
;
37 static int tda665x_read(struct tda665x_state
*state
, u8
*buf
)
39 const struct tda665x_config
*config
= state
->config
;
41 struct i2c_msg msg
= { .addr
= config
->addr
, .flags
= I2C_M_RD
, .buf
= buf
, .len
= 2 };
43 err
= i2c_transfer(state
->i2c
, &msg
, 1);
49 printk(KERN_ERR
"%s: I/O Error err=<%d>\n", __func__
, err
);
53 static int tda665x_write(struct tda665x_state
*state
, u8
*buf
, u8 length
)
55 const struct tda665x_config
*config
= state
->config
;
57 struct i2c_msg msg
= { .addr
= config
->addr
, .flags
= 0, .buf
= buf
, .len
= length
};
59 err
= i2c_transfer(state
->i2c
, &msg
, 1);
65 printk(KERN_ERR
"%s: I/O Error err=<%d>\n", __func__
, err
);
69 static int tda665x_get_frequency(struct dvb_frontend
*fe
, u32
*frequency
)
71 struct tda665x_state
*state
= fe
->tuner_priv
;
73 *frequency
= state
->frequency
;
78 static int tda665x_get_status(struct dvb_frontend
*fe
, u32
*status
)
80 struct tda665x_state
*state
= fe
->tuner_priv
;
86 err
= tda665x_read(state
, &result
);
90 if ((result
>> 6) & 0x01) {
91 printk(KERN_DEBUG
"%s: Tuner Phase Locked\n", __func__
);
97 printk(KERN_ERR
"%s: I/O Error\n", __func__
);
101 static int tda665x_set_frequency(struct dvb_frontend
*fe
,
104 struct tda665x_state
*state
= fe
->tuner_priv
;
105 const struct tda665x_config
*config
= state
->config
;
106 u32 frequency
, status
= 0;
110 if ((new_frequency
< config
->frequency_max
)
111 || (new_frequency
> config
->frequency_min
)) {
112 printk(KERN_ERR
"%s: Frequency beyond limits, frequency=%d\n",
113 __func__
, new_frequency
);
117 frequency
= new_frequency
;
119 frequency
+= config
->frequency_offst
;
120 frequency
*= config
->ref_multiplier
;
121 frequency
+= config
->ref_divider
>> 1;
122 frequency
/= config
->ref_divider
;
124 buf
[0] = (u8
) ((frequency
& 0x7f00) >> 8);
125 buf
[1] = (u8
) (frequency
& 0x00ff) >> 0;
126 buf
[2] = 0x80 | 0x40 | 0x02;
129 /* restore frequency */
130 frequency
= new_frequency
;
132 if (frequency
< 153000000) {
134 buf
[3] |= 0x01; /* fc, Low Band, 47 - 153 MHz */
135 if (frequency
< 68000000)
136 buf
[3] |= 0x40; /* 83uA */
137 if (frequency
< 1040000000)
138 buf
[3] |= 0x60; /* 122uA */
139 if (frequency
< 1250000000)
140 buf
[3] |= 0x80; /* 163uA */
142 buf
[3] |= 0xa0; /* 254uA */
143 } else if (frequency
< 438000000) {
145 buf
[3] |= 0x02; /* fc, Mid Band, 153 - 438 MHz */
146 if (frequency
< 230000000)
148 if (frequency
< 300000000)
154 buf
[3] |= 0x04; /* fc, High Band, 438 - 862 MHz */
155 if (frequency
< 470000000)
157 if (frequency
< 526000000)
164 err
= tda665x_write(state
, buf
, 5);
168 /* sleep for some time */
169 printk(KERN_DEBUG
"%s: Waiting to Phase LOCK\n", __func__
);
172 err
= tda665x_get_status(fe
, &status
);
177 printk(KERN_DEBUG
"%s: Tuner Phase locked: status=%d\n",
179 state
->frequency
= frequency
; /* cache successful state */
181 printk(KERN_ERR
"%s: No Phase lock: status=%d\n",
187 printk(KERN_ERR
"%s: I/O Error\n", __func__
);
191 static int tda665x_set_params(struct dvb_frontend
*fe
)
193 struct dtv_frontend_properties
*c
= &fe
->dtv_property_cache
;
195 tda665x_set_frequency(fe
, c
->frequency
);
200 static void tda665x_release(struct dvb_frontend
*fe
)
202 struct tda665x_state
*state
= fe
->tuner_priv
;
204 fe
->tuner_priv
= NULL
;
208 static const struct dvb_tuner_ops tda665x_ops
= {
209 .get_status
= tda665x_get_status
,
210 .set_params
= tda665x_set_params
,
211 .get_frequency
= tda665x_get_frequency
,
212 .release
= tda665x_release
215 struct dvb_frontend
*tda665x_attach(struct dvb_frontend
*fe
,
216 const struct tda665x_config
*config
,
217 struct i2c_adapter
*i2c
)
219 struct tda665x_state
*state
= NULL
;
220 struct dvb_tuner_info
*info
;
222 state
= kzalloc(sizeof(struct tda665x_state
), GFP_KERNEL
);
226 state
->config
= config
;
229 fe
->tuner_priv
= state
;
230 fe
->ops
.tuner_ops
= tda665x_ops
;
231 info
= &fe
->ops
.tuner_ops
.info
;
233 memcpy(info
->name
, config
->name
, sizeof(config
->name
));
234 info
->frequency_min
= config
->frequency_min
;
235 info
->frequency_max
= config
->frequency_max
;
236 info
->frequency_step
= config
->frequency_offst
;
238 printk(KERN_DEBUG
"%s: Attaching TDA665x (%s) tuner\n", __func__
, info
->name
);
242 EXPORT_SYMBOL(tda665x_attach
);
244 MODULE_DESCRIPTION("TDA665x driver");
245 MODULE_AUTHOR("Manu Abraham");
246 MODULE_LICENSE("GPL");