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>
24 #include "dvb_frontend.h"
27 struct tda665x_state
{
28 struct dvb_frontend
*fe
;
29 struct i2c_adapter
*i2c
;
30 const struct tda665x_config
*config
;
36 static int tda665x_read(struct tda665x_state
*state
, u8
*buf
)
38 const struct tda665x_config
*config
= state
->config
;
40 struct i2c_msg msg
= { .addr
= config
->addr
, .flags
= I2C_M_RD
, .buf
= buf
, .len
= 2 };
42 err
= i2c_transfer(state
->i2c
, &msg
, 1);
48 printk(KERN_ERR
"%s: I/O Error err=<%d>\n", __func__
, err
);
52 static int tda665x_write(struct tda665x_state
*state
, u8
*buf
, u8 length
)
54 const struct tda665x_config
*config
= state
->config
;
56 struct i2c_msg msg
= { .addr
= config
->addr
, .flags
= 0, .buf
= buf
, .len
= length
};
58 err
= i2c_transfer(state
->i2c
, &msg
, 1);
64 printk(KERN_ERR
"%s: I/O Error err=<%d>\n", __func__
, err
);
68 static int tda665x_get_state(struct dvb_frontend
*fe
,
69 enum tuner_param param
,
70 struct tuner_state
*tstate
)
72 struct tda665x_state
*state
= fe
->tuner_priv
;
76 case DVBFE_TUNER_FREQUENCY
:
77 tstate
->frequency
= state
->frequency
;
79 case DVBFE_TUNER_BANDWIDTH
:
82 printk(KERN_ERR
"%s: Unknown parameter (param=%d)\n", __func__
, param
);
90 static int tda665x_get_status(struct dvb_frontend
*fe
, u32
*status
)
92 struct tda665x_state
*state
= fe
->tuner_priv
;
98 err
= tda665x_read(state
, &result
);
102 if ((result
>> 6) & 0x01) {
103 printk(KERN_DEBUG
"%s: Tuner Phase Locked\n", __func__
);
109 printk(KERN_ERR
"%s: I/O Error\n", __func__
);
113 static int tda665x_set_state(struct dvb_frontend
*fe
,
114 enum tuner_param param
,
115 struct tuner_state
*tstate
)
117 struct tda665x_state
*state
= fe
->tuner_priv
;
118 const struct tda665x_config
*config
= state
->config
;
119 u32 frequency
, status
= 0;
123 if (param
& DVBFE_TUNER_FREQUENCY
) {
125 frequency
= tstate
->frequency
;
126 if ((frequency
< config
->frequency_max
) || (frequency
> config
->frequency_min
)) {
127 printk(KERN_ERR
"%s: Frequency beyond limits, frequency=%d\n", __func__
, frequency
);
131 frequency
+= config
->frequency_offst
;
132 frequency
*= config
->ref_multiplier
;
133 frequency
+= config
->ref_divider
>> 1;
134 frequency
/= config
->ref_divider
;
136 buf
[0] = (u8
) ((frequency
& 0x7f00) >> 8);
137 buf
[1] = (u8
) (frequency
& 0x00ff) >> 0;
138 buf
[2] = 0x80 | 0x40 | 0x02;
141 /* restore frequency */
142 frequency
= tstate
->frequency
;
144 if (frequency
< 153000000) {
146 buf
[3] |= 0x01; /* fc, Low Band, 47 - 153 MHz */
147 if (frequency
< 68000000)
148 buf
[3] |= 0x40; /* 83uA */
149 if (frequency
< 1040000000)
150 buf
[3] |= 0x60; /* 122uA */
151 if (frequency
< 1250000000)
152 buf
[3] |= 0x80; /* 163uA */
154 buf
[3] |= 0xa0; /* 254uA */
155 } else if (frequency
< 438000000) {
157 buf
[3] |= 0x02; /* fc, Mid Band, 153 - 438 MHz */
158 if (frequency
< 230000000)
160 if (frequency
< 300000000)
166 buf
[3] |= 0x04; /* fc, High Band, 438 - 862 MHz */
167 if (frequency
< 470000000)
169 if (frequency
< 526000000)
176 err
= tda665x_write(state
, buf
, 5);
180 /* sleep for some time */
181 printk(KERN_DEBUG
"%s: Waiting to Phase LOCK\n", __func__
);
184 err
= tda665x_get_status(fe
, &status
);
189 printk(KERN_DEBUG
"%s: Tuner Phase locked: status=%d\n", __func__
, status
);
190 state
->frequency
= frequency
; /* cache successful state */
192 printk(KERN_ERR
"%s: No Phase lock: status=%d\n", __func__
, status
);
195 printk(KERN_ERR
"%s: Unknown parameter (param=%d)\n", __func__
, param
);
201 printk(KERN_ERR
"%s: I/O Error\n", __func__
);
205 static int tda665x_release(struct dvb_frontend
*fe
)
207 struct tda665x_state
*state
= fe
->tuner_priv
;
209 fe
->tuner_priv
= NULL
;
214 static struct dvb_tuner_ops tda665x_ops
= {
216 .set_state
= tda665x_set_state
,
217 .get_state
= tda665x_get_state
,
218 .get_status
= tda665x_get_status
,
219 .release
= tda665x_release
222 struct dvb_frontend
*tda665x_attach(struct dvb_frontend
*fe
,
223 const struct tda665x_config
*config
,
224 struct i2c_adapter
*i2c
)
226 struct tda665x_state
*state
= NULL
;
227 struct dvb_tuner_info
*info
;
229 state
= kzalloc(sizeof(struct tda665x_state
), GFP_KERNEL
);
233 state
->config
= config
;
236 fe
->tuner_priv
= state
;
237 fe
->ops
.tuner_ops
= tda665x_ops
;
238 info
= &fe
->ops
.tuner_ops
.info
;
240 memcpy(info
->name
, config
->name
, sizeof(config
->name
));
241 info
->frequency_min
= config
->frequency_min
;
242 info
->frequency_max
= config
->frequency_max
;
243 info
->frequency_step
= config
->frequency_offst
;
245 printk(KERN_DEBUG
"%s: Attaching TDA665x (%s) tuner\n", __func__
, info
->name
);
253 EXPORT_SYMBOL(tda665x_attach
);
255 MODULE_DESCRIPTION("TDA665x driver");
256 MODULE_AUTHOR("Manu Abraham");
257 MODULE_LICENSE("GPL");