Merge branch 'origin'
[pandora-kernel.git] / drivers / media / dvb / frontends / lnbp21.h
1 /*
2  * lnbp21.h - driver for lnb supply and control ic lnbp21
3  *
4  * Copyright (C) 2006 Oliver Endriss
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
22  *
23  *
24  * the project's page is at http://www.linuxtv.org
25  */
26
27 #ifndef _LNBP21_H
28 #define _LNBP21_H
29
30 /* system register */
31 #define LNBP21_OLF      0x01
32 #define LNBP21_OTF      0x02
33 #define LNBP21_EN       0x04
34 #define LNBP21_VSEL     0x08
35 #define LNBP21_LLC      0x10
36 #define LNBP21_TEN      0x20
37 #define LNBP21_ISEL     0x40
38 #define LNBP21_PCL      0x80
39
40 struct lnbp21 {
41         u8                      config;
42         u8                      override_or;
43         u8                      override_and;
44         struct i2c_adapter      *i2c;
45         void                    (*release_chain)(struct dvb_frontend* fe);
46 };
47
48 static int lnbp21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
49 {
50         struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv;
51         struct i2c_msg msg = {  .addr = 0x08, .flags = 0,
52                                 .buf = &lnbp21->config,
53                                 .len = sizeof(lnbp21->config) };
54
55         lnbp21->config &= ~(LNBP21_VSEL | LNBP21_EN);
56
57         switch(voltage) {
58         case SEC_VOLTAGE_OFF:
59                 break;
60         case SEC_VOLTAGE_13:
61                 lnbp21->config |= LNBP21_EN;
62                 break;
63         case SEC_VOLTAGE_18:
64                 lnbp21->config |= (LNBP21_EN | LNBP21_VSEL);
65                 break;
66         default:
67                 return -EINVAL;
68         };
69
70         lnbp21->config |= lnbp21->override_or;
71         lnbp21->config &= lnbp21->override_and;
72
73         return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
74 }
75
76 static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
77 {
78         struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv;
79         struct i2c_msg msg = {  .addr = 0x08, .flags = 0,
80                                 .buf = &lnbp21->config,
81                                 .len = sizeof(lnbp21->config) };
82
83         if (arg)
84                 lnbp21->config |= LNBP21_LLC;
85         else
86                 lnbp21->config &= ~LNBP21_LLC;
87
88         lnbp21->config |= lnbp21->override_or;
89         lnbp21->config &= lnbp21->override_and;
90
91         return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
92 }
93
94 static void lnbp21_exit(struct dvb_frontend *fe)
95 {
96         struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv;
97
98         /* LNBP power off */
99         lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF);
100
101         /* free data & call next release routine */
102         fe->ops->release = lnbp21->release_chain;
103         kfree(fe->misc_priv);
104         fe->misc_priv = NULL;
105         if (fe->ops->release)
106                 fe->ops->release(fe);
107 }
108
109 static int lnbp21_init(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear)
110 {
111         struct lnbp21 *lnbp21 = kmalloc(sizeof(struct lnbp21), GFP_KERNEL);
112
113         if (!lnbp21)
114                 return -ENOMEM;
115
116         /* default configuration */
117         lnbp21->config = LNBP21_ISEL;
118
119         /* bits which should be forced to '1' */
120         lnbp21->override_or = override_set;
121
122         /* bits which should be forced to '0' */
123         lnbp21->override_and = ~override_clear;
124
125         /* install release callback */
126         lnbp21->release_chain = fe->ops->release;
127         fe->ops->release = lnbp21_exit;
128
129         /* override frontend ops */
130         fe->ops->set_voltage = lnbp21_set_voltage;
131         fe->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
132
133         lnbp21->i2c = i2c;
134         fe->misc_priv = lnbp21;
135
136         return lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF);
137 }
138
139 #endif