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_state(struct dvb_frontend
*fe
,
70 enum tuner_param param
,
71 struct tuner_state
*tstate
)
73 struct tda665x_state
*state
= fe
->tuner_priv
;
77 case DVBFE_TUNER_FREQUENCY
:
78 tstate
->frequency
= state
->frequency
;
80 case DVBFE_TUNER_BANDWIDTH
:
83 printk(KERN_ERR
"%s: Unknown parameter (param=%d)\n", __func__
, param
);
91 static int tda665x_get_status(struct dvb_frontend
*fe
, u32
*status
)
93 struct tda665x_state
*state
= fe
->tuner_priv
;
99 err
= tda665x_read(state
, &result
);
103 if ((result
>> 6) & 0x01) {
104 printk(KERN_DEBUG
"%s: Tuner Phase Locked\n", __func__
);
110 printk(KERN_ERR
"%s: I/O Error\n", __func__
);
114 static int tda665x_set_state(struct dvb_frontend
*fe
,
115 enum tuner_param param
,
116 struct tuner_state
*tstate
)
118 struct tda665x_state
*state
= fe
->tuner_priv
;
119 const struct tda665x_config
*config
= state
->config
;
120 u32 frequency
, status
= 0;
124 if (param
& DVBFE_TUNER_FREQUENCY
) {
126 frequency
= tstate
->frequency
;
127 if ((frequency
< config
->frequency_max
) || (frequency
> config
->frequency_min
)) {
128 printk(KERN_ERR
"%s: Frequency beyond limits, frequency=%d\n", __func__
, frequency
);
132 frequency
+= config
->frequency_offst
;
133 frequency
*= config
->ref_multiplier
;
134 frequency
+= config
->ref_divider
>> 1;
135 frequency
/= config
->ref_divider
;
137 buf
[0] = (u8
) ((frequency
& 0x7f00) >> 8);
138 buf
[1] = (u8
) (frequency
& 0x00ff) >> 0;
139 buf
[2] = 0x80 | 0x40 | 0x02;
142 /* restore frequency */
143 frequency
= tstate
->frequency
;
145 if (frequency
< 153000000) {
147 buf
[3] |= 0x01; /* fc, Low Band, 47 - 153 MHz */
148 if (frequency
< 68000000)
149 buf
[3] |= 0x40; /* 83uA */
150 if (frequency
< 1040000000)
151 buf
[3] |= 0x60; /* 122uA */
152 if (frequency
< 1250000000)
153 buf
[3] |= 0x80; /* 163uA */
155 buf
[3] |= 0xa0; /* 254uA */
156 } else if (frequency
< 438000000) {
158 buf
[3] |= 0x02; /* fc, Mid Band, 153 - 438 MHz */
159 if (frequency
< 230000000)
161 if (frequency
< 300000000)
167 buf
[3] |= 0x04; /* fc, High Band, 438 - 862 MHz */
168 if (frequency
< 470000000)
170 if (frequency
< 526000000)
177 err
= tda665x_write(state
, buf
, 5);
181 /* sleep for some time */
182 printk(KERN_DEBUG
"%s: Waiting to Phase LOCK\n", __func__
);
185 err
= tda665x_get_status(fe
, &status
);
190 printk(KERN_DEBUG
"%s: Tuner Phase locked: status=%d\n", __func__
, status
);
191 state
->frequency
= frequency
; /* cache successful state */
193 printk(KERN_ERR
"%s: No Phase lock: status=%d\n", __func__
, status
);
196 printk(KERN_ERR
"%s: Unknown parameter (param=%d)\n", __func__
, param
);
202 printk(KERN_ERR
"%s: I/O Error\n", __func__
);
206 static int tda665x_release(struct dvb_frontend
*fe
)
208 struct tda665x_state
*state
= fe
->tuner_priv
;
210 fe
->tuner_priv
= NULL
;
215 static struct dvb_tuner_ops tda665x_ops
= {
217 .set_state
= tda665x_set_state
,
218 .get_state
= tda665x_get_state
,
219 .get_status
= tda665x_get_status
,
220 .release
= tda665x_release
223 struct dvb_frontend
*tda665x_attach(struct dvb_frontend
*fe
,
224 const struct tda665x_config
*config
,
225 struct i2c_adapter
*i2c
)
227 struct tda665x_state
*state
= NULL
;
228 struct dvb_tuner_info
*info
;
230 state
= kzalloc(sizeof(struct tda665x_state
), GFP_KERNEL
);
234 state
->config
= config
;
237 fe
->tuner_priv
= state
;
238 fe
->ops
.tuner_ops
= tda665x_ops
;
239 info
= &fe
->ops
.tuner_ops
.info
;
241 memcpy(info
->name
, config
->name
, sizeof(config
->name
));
242 info
->frequency_min
= config
->frequency_min
;
243 info
->frequency_max
= config
->frequency_max
;
244 info
->frequency_step
= config
->frequency_offst
;
246 printk(KERN_DEBUG
"%s: Attaching TDA665x (%s) tuner\n", __func__
, info
->name
);
250 EXPORT_SYMBOL(tda665x_attach
);
252 MODULE_DESCRIPTION("TDA665x driver");
253 MODULE_AUTHOR("Manu Abraham");
254 MODULE_LICENSE("GPL");