Commit | Line | Data |
---|---|---|
85bc9b51 AP |
1 | /* |
2 | * Allegro A8293 SEC driver | |
3 | * | |
4 | * Copyright (C) 2011 Antti Palosaari <crope@iki.fi> | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License as published by | |
8 | * the Free Software Foundation; either version 2 of the License, or | |
9 | * (at your option) any later version. | |
10 | * | |
11 | * This program is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | * GNU General Public License for more details. | |
85bc9b51 AP |
15 | */ |
16 | ||
85bc9b51 AP |
17 | #include "a8293.h" |
18 | ||
2c509b86 | 19 | struct a8293_dev { |
b561baec | 20 | struct i2c_client *client; |
85bc9b51 AP |
21 | u8 reg[2]; |
22 | }; | |
23 | ||
85bc9b51 | 24 | static int a8293_set_voltage(struct dvb_frontend *fe, |
3250a550 | 25 | enum fe_sec_voltage fe_sec_voltage) |
85bc9b51 | 26 | { |
2c509b86 AP |
27 | struct a8293_dev *dev = fe->sec_priv; |
28 | struct i2c_client *client = dev->client; | |
85bc9b51 | 29 | int ret; |
4bef67e3 | 30 | u8 reg0, reg1; |
85bc9b51 | 31 | |
2c509b86 | 32 | dev_dbg(&client->dev, "fe_sec_voltage=%d\n", fe_sec_voltage); |
85bc9b51 AP |
33 | |
34 | switch (fe_sec_voltage) { | |
35 | case SEC_VOLTAGE_OFF: | |
36 | /* ENB=0 */ | |
4bef67e3 | 37 | reg0 = 0x10; |
85bc9b51 AP |
38 | break; |
39 | case SEC_VOLTAGE_13: | |
40 | /* VSEL0=1, VSEL1=0, VSEL2=0, VSEL3=0, ENB=1*/ | |
4bef67e3 | 41 | reg0 = 0x31; |
85bc9b51 AP |
42 | break; |
43 | case SEC_VOLTAGE_18: | |
44 | /* VSEL0=0, VSEL1=0, VSEL2=0, VSEL3=1, ENB=1*/ | |
4bef67e3 | 45 | reg0 = 0x38; |
85bc9b51 AP |
46 | break; |
47 | default: | |
48 | ret = -EINVAL; | |
49 | goto err; | |
c2c1b415 | 50 | } |
4bef67e3 AP |
51 | if (reg0 != dev->reg[0]) { |
52 | ret = i2c_master_send(client, ®0, 1); | |
53 | if (ret < 0) | |
54 | goto err; | |
55 | dev->reg[0] = reg0; | |
56 | } | |
85bc9b51 | 57 | |
4bef67e3 AP |
58 | /* TMODE=0, TGATE=1 */ |
59 | reg1 = 0x82; | |
60 | if (reg1 != dev->reg[1]) { | |
61 | ret = i2c_master_send(client, ®1, 1); | |
62 | if (ret < 0) | |
63 | goto err; | |
64 | dev->reg[1] = reg1; | |
65 | } | |
85bc9b51 | 66 | |
c0ec1c4d | 67 | usleep_range(1500, 50000); |
2c509b86 | 68 | return 0; |
85bc9b51 | 69 | err: |
2c509b86 | 70 | dev_dbg(&client->dev, "failed=%d\n", ret); |
85bc9b51 AP |
71 | return ret; |
72 | } | |
73 | ||
b561baec | 74 | static int a8293_probe(struct i2c_client *client, |
55881b4f | 75 | const struct i2c_device_id *id) |
b561baec | 76 | { |
2c509b86 | 77 | struct a8293_dev *dev; |
b561baec AP |
78 | struct a8293_platform_data *pdata = client->dev.platform_data; |
79 | struct dvb_frontend *fe = pdata->dvb_frontend; | |
80 | int ret; | |
81 | u8 buf[2]; | |
82 | ||
83 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | |
84 | if (!dev) { | |
85 | ret = -ENOMEM; | |
86 | goto err; | |
87 | } | |
88 | ||
89 | dev->client = client; | |
b561baec AP |
90 | |
91 | /* check if the SEC is there */ | |
2c509b86 AP |
92 | ret = i2c_master_recv(client, buf, 2); |
93 | if (ret < 0) | |
b561baec AP |
94 | goto err_kfree; |
95 | ||
b561baec AP |
96 | /* override frontend ops */ |
97 | fe->ops.set_voltage = a8293_set_voltage; | |
b561baec AP |
98 | fe->sec_priv = dev; |
99 | i2c_set_clientdata(client, dev); | |
100 | ||
101 | dev_info(&client->dev, "Allegro A8293 SEC successfully attached\n"); | |
102 | return 0; | |
103 | err_kfree: | |
104 | kfree(dev); | |
105 | err: | |
106 | dev_dbg(&client->dev, "failed=%d\n", ret); | |
107 | return ret; | |
108 | } | |
109 | ||
110 | static int a8293_remove(struct i2c_client *client) | |
111 | { | |
112 | struct a8293_dev *dev = i2c_get_clientdata(client); | |
113 | ||
114 | dev_dbg(&client->dev, "\n"); | |
115 | ||
116 | kfree(dev); | |
117 | return 0; | |
118 | } | |
119 | ||
120 | static const struct i2c_device_id a8293_id_table[] = { | |
121 | {"a8293", 0}, | |
122 | {} | |
123 | }; | |
124 | MODULE_DEVICE_TABLE(i2c, a8293_id_table); | |
125 | ||
126 | static struct i2c_driver a8293_driver = { | |
127 | .driver = { | |
b561baec AP |
128 | .name = "a8293", |
129 | .suppress_bind_attrs = true, | |
130 | }, | |
131 | .probe = a8293_probe, | |
132 | .remove = a8293_remove, | |
133 | .id_table = a8293_id_table, | |
134 | }; | |
135 | ||
136 | module_i2c_driver(a8293_driver); | |
137 | ||
85bc9b51 AP |
138 | MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); |
139 | MODULE_DESCRIPTION("Allegro A8293 SEC driver"); | |
140 | MODULE_LICENSE("GPL"); |