This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / drivers / media / dvb / frontends / lgh06xf.c
1 /*
2  *  lgh06xf.c - ATSC Tuner support for LG TDVS-H06xF
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18
19 #include "dvb-pll.h"
20 #include "lgh06xf.h"
21
22 #define LG_H06XF_PLL_I2C_ADDR 0x61
23
24 struct lgh06xf_priv {
25         struct i2c_adapter *i2c;
26         u32 frequency;
27 };
28
29 static int lgh06xf_release(struct dvb_frontend *fe)
30 {
31         kfree(fe->tuner_priv);
32         fe->tuner_priv = NULL;
33         return 0;
34 }
35
36 static int lgh06xf_set_params(struct dvb_frontend* fe,
37                               struct dvb_frontend_parameters* params)
38 {
39         struct lgh06xf_priv *priv = fe->tuner_priv;
40         u8 buf[4];
41         struct i2c_msg msg = { .addr = LG_H06XF_PLL_I2C_ADDR, .flags = 0,
42                                .buf = buf, .len = sizeof(buf) };
43         u32 frequency;
44         int result;
45
46         if ((result = dvb_pll_configure(&dvb_pll_lg_tdvs_h06xf, buf,
47                                         params->frequency, 0)) < 0)
48                 return result;
49         else
50                 frequency = result;
51
52         if (fe->ops.i2c_gate_ctrl)
53                 fe->ops.i2c_gate_ctrl(fe, 1);
54         if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) {
55                 printk(KERN_WARNING "lgh06xf: %s error "
56                        "(addr %02x <- %02x, result = %i)\n",
57                        __FUNCTION__, buf[0], buf[1], result);
58                 if (result < 0)
59                         return result;
60                 else
61                         return -EREMOTEIO;
62         }
63
64         /* Set the Auxiliary Byte. */
65         buf[0] = buf[2];
66         buf[0] &= ~0x20;
67         buf[0] |= 0x18;
68         buf[1] = 0x50;
69         msg.len = 2;
70         if (fe->ops.i2c_gate_ctrl)
71                 fe->ops.i2c_gate_ctrl(fe, 1);
72         if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) {
73                 printk(KERN_WARNING "lgh06xf: %s error "
74                        "(addr %02x <- %02x, result = %i)\n",
75                        __FUNCTION__, buf[0], buf[1], result);
76                 if (result < 0)
77                         return result;
78                 else
79                         return -EREMOTEIO;
80         }
81
82         priv->frequency = frequency;
83
84         return 0;
85 }
86
87 static int lgh06xf_get_frequency(struct dvb_frontend *fe, u32 *frequency)
88 {
89         struct lgh06xf_priv *priv = fe->tuner_priv;
90         *frequency = priv->frequency;
91         return 0;
92 }
93
94 static struct dvb_tuner_ops lgh06xf_tuner_ops = {
95         .release       = lgh06xf_release,
96         .set_params    = lgh06xf_set_params,
97         .get_frequency = lgh06xf_get_frequency,
98 };
99
100 struct dvb_frontend* lgh06xf_attach(struct dvb_frontend *fe,
101                                     struct i2c_adapter *i2c)
102 {
103         struct lgh06xf_priv *priv = NULL;
104
105         priv = kzalloc(sizeof(struct lgh06xf_priv), GFP_KERNEL);
106         if (priv == NULL)
107                 return NULL;
108
109         priv->i2c = i2c;
110
111         memcpy(&fe->ops.tuner_ops, &lgh06xf_tuner_ops,
112                sizeof(struct dvb_tuner_ops));
113
114         strlcpy(fe->ops.tuner_ops.info.name, dvb_pll_lg_tdvs_h06xf.name,
115                 sizeof(fe->ops.tuner_ops.info.name));
116
117         fe->ops.tuner_ops.info.frequency_min = dvb_pll_lg_tdvs_h06xf.min;
118         fe->ops.tuner_ops.info.frequency_max = dvb_pll_lg_tdvs_h06xf.max;
119
120         fe->tuner_priv = priv;
121         return fe;
122 }
123
124 EXPORT_SYMBOL(lgh06xf_attach);
125
126 MODULE_DESCRIPTION("LG TDVS-H06xF ATSC Tuner support");
127 MODULE_AUTHOR("Michael Krufky");
128 MODULE_LICENSE("GPL");
129
130 /*
131  * Local variables:
132  * c-basic-offset: 8
133  * End:
134  */