Merge tag 'arc-5.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc
[sfrench/cifs-2.6.git] / drivers / media / pci / cx18 / cx18-i2c.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *  cx18 I2C functions
4  *
5  *  Derived from ivtv-i2c.c
6  *
7  *  Copyright (C) 2007  Hans Verkuil <hverkuil@xs4all.nl>
8  *  Copyright (C) 2008  Andy Walls <awalls@md.metrocast.net>
9  */
10
11 #include "cx18-driver.h"
12 #include "cx18-io.h"
13 #include "cx18-cards.h"
14 #include "cx18-gpio.h"
15 #include "cx18-i2c.h"
16 #include "cx18-irq.h"
17
18 #define CX18_REG_I2C_1_WR   0xf15000
19 #define CX18_REG_I2C_1_RD   0xf15008
20 #define CX18_REG_I2C_2_WR   0xf25100
21 #define CX18_REG_I2C_2_RD   0xf25108
22
23 #define SETSCL_BIT      0x0001
24 #define SETSDL_BIT      0x0002
25 #define GETSCL_BIT      0x0004
26 #define GETSDL_BIT      0x0008
27
28 #define CX18_CS5345_I2C_ADDR            0x4c
29 #define CX18_Z8F0811_IR_TX_I2C_ADDR     0x70
30 #define CX18_Z8F0811_IR_RX_I2C_ADDR     0x71
31
32 /* This array should match the CX18_HW_ defines */
33 static const u8 hw_addrs[] = {
34         0,                              /* CX18_HW_TUNER */
35         0,                              /* CX18_HW_TVEEPROM */
36         CX18_CS5345_I2C_ADDR,           /* CX18_HW_CS5345 */
37         0,                              /* CX18_HW_DVB */
38         0,                              /* CX18_HW_418_AV */
39         0,                              /* CX18_HW_GPIO_MUX */
40         0,                              /* CX18_HW_GPIO_RESET_CTRL */
41         CX18_Z8F0811_IR_RX_I2C_ADDR,    /* CX18_HW_Z8F0811_IR_HAUP */
42 };
43
44 /* This array should match the CX18_HW_ defines */
45 /* This might well become a card-specific array */
46 static const u8 hw_bus[] = {
47         1,      /* CX18_HW_TUNER */
48         0,      /* CX18_HW_TVEEPROM */
49         0,      /* CX18_HW_CS5345 */
50         0,      /* CX18_HW_DVB */
51         0,      /* CX18_HW_418_AV */
52         0,      /* CX18_HW_GPIO_MUX */
53         0,      /* CX18_HW_GPIO_RESET_CTRL */
54         0,      /* CX18_HW_Z8F0811_IR_HAUP */
55 };
56
57 /* This array should match the CX18_HW_ defines */
58 static const char * const hw_devicenames[] = {
59         "tuner",
60         "tveeprom",
61         "cs5345",
62         "cx23418_DTV",
63         "cx23418_AV",
64         "gpio_mux",
65         "gpio_reset_ctrl",
66         "ir_z8f0811_haup",
67 };
68
69 static int cx18_i2c_new_ir(struct cx18 *cx, struct i2c_adapter *adap, u32 hw,
70                            const char *type, u8 addr)
71 {
72         struct i2c_board_info info;
73         struct IR_i2c_init_data *init_data = &cx->ir_i2c_init_data;
74         unsigned short addr_list[2] = { addr, I2C_CLIENT_END };
75
76         memset(&info, 0, sizeof(struct i2c_board_info));
77         strscpy(info.type, type, I2C_NAME_SIZE);
78
79         /* Our default information for ir-kbd-i2c.c to use */
80         switch (hw) {
81         case CX18_HW_Z8F0811_IR_HAUP:
82                 init_data->ir_codes = RC_MAP_HAUPPAUGE;
83                 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
84                 init_data->type = RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC6_MCE |
85                                                         RC_PROTO_BIT_RC6_6A_32;
86                 init_data->name = cx->card_name;
87                 info.platform_data = init_data;
88                 break;
89         }
90
91         return i2c_new_probed_device(adap, &info, addr_list, NULL) == NULL ?
92                -1 : 0;
93 }
94
95 int cx18_i2c_register(struct cx18 *cx, unsigned idx)
96 {
97         struct v4l2_subdev *sd;
98         int bus = hw_bus[idx];
99         struct i2c_adapter *adap = &cx->i2c_adap[bus];
100         const char *type = hw_devicenames[idx];
101         u32 hw = 1 << idx;
102
103         if (hw == CX18_HW_TUNER) {
104                 /* special tuner group handling */
105                 sd = v4l2_i2c_new_subdev(&cx->v4l2_dev,
106                                 adap, type, 0, cx->card_i2c->radio);
107                 if (sd != NULL)
108                         sd->grp_id = hw;
109                 sd = v4l2_i2c_new_subdev(&cx->v4l2_dev,
110                                 adap, type, 0, cx->card_i2c->demod);
111                 if (sd != NULL)
112                         sd->grp_id = hw;
113                 sd = v4l2_i2c_new_subdev(&cx->v4l2_dev,
114                                 adap, type, 0, cx->card_i2c->tv);
115                 if (sd != NULL)
116                         sd->grp_id = hw;
117                 return sd != NULL ? 0 : -1;
118         }
119
120         if (hw == CX18_HW_Z8F0811_IR_HAUP)
121                 return cx18_i2c_new_ir(cx, adap, hw, type, hw_addrs[idx]);
122
123         /* Is it not an I2C device or one we do not wish to register? */
124         if (!hw_addrs[idx])
125                 return -1;
126
127         /* It's an I2C device other than an analog tuner or IR chip */
128         sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, adap, type, hw_addrs[idx],
129                                  NULL);
130         if (sd != NULL)
131                 sd->grp_id = hw;
132         return sd != NULL ? 0 : -1;
133 }
134
135 /* Find the first member of the subdev group id in hw */
136 struct v4l2_subdev *cx18_find_hw(struct cx18 *cx, u32 hw)
137 {
138         struct v4l2_subdev *result = NULL;
139         struct v4l2_subdev *sd;
140
141         spin_lock(&cx->v4l2_dev.lock);
142         v4l2_device_for_each_subdev(sd, &cx->v4l2_dev) {
143                 if (sd->grp_id == hw) {
144                         result = sd;
145                         break;
146                 }
147         }
148         spin_unlock(&cx->v4l2_dev.lock);
149         return result;
150 }
151
152 static void cx18_setscl(void *data, int state)
153 {
154         struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
155         int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
156         u32 addr = bus_index ? CX18_REG_I2C_2_WR : CX18_REG_I2C_1_WR;
157         u32 r = cx18_read_reg(cx, addr);
158
159         if (state)
160                 cx18_write_reg(cx, r | SETSCL_BIT, addr);
161         else
162                 cx18_write_reg(cx, r & ~SETSCL_BIT, addr);
163 }
164
165 static void cx18_setsda(void *data, int state)
166 {
167         struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
168         int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
169         u32 addr = bus_index ? CX18_REG_I2C_2_WR : CX18_REG_I2C_1_WR;
170         u32 r = cx18_read_reg(cx, addr);
171
172         if (state)
173                 cx18_write_reg(cx, r | SETSDL_BIT, addr);
174         else
175                 cx18_write_reg(cx, r & ~SETSDL_BIT, addr);
176 }
177
178 static int cx18_getscl(void *data)
179 {
180         struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
181         int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
182         u32 addr = bus_index ? CX18_REG_I2C_2_RD : CX18_REG_I2C_1_RD;
183
184         return cx18_read_reg(cx, addr) & GETSCL_BIT;
185 }
186
187 static int cx18_getsda(void *data)
188 {
189         struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
190         int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
191         u32 addr = bus_index ? CX18_REG_I2C_2_RD : CX18_REG_I2C_1_RD;
192
193         return cx18_read_reg(cx, addr) & GETSDL_BIT;
194 }
195
196 /* template for i2c-bit-algo */
197 static const struct i2c_adapter cx18_i2c_adap_template = {
198         .name = "cx18 i2c driver",
199         .algo = NULL,                   /* set by i2c-algo-bit */
200         .algo_data = NULL,              /* filled from template */
201         .owner = THIS_MODULE,
202 };
203
204 #define CX18_SCL_PERIOD (10) /* usecs. 10 usec is period for a 100 KHz clock */
205 #define CX18_ALGO_BIT_TIMEOUT (2) /* seconds */
206
207 static const struct i2c_algo_bit_data cx18_i2c_algo_template = {
208         .setsda         = cx18_setsda,
209         .setscl         = cx18_setscl,
210         .getsda         = cx18_getsda,
211         .getscl         = cx18_getscl,
212         .udelay         = CX18_SCL_PERIOD/2,       /* 1/2 clock period in usec*/
213         .timeout        = CX18_ALGO_BIT_TIMEOUT*HZ /* jiffies */
214 };
215
216 /* init + register i2c adapter */
217 int init_cx18_i2c(struct cx18 *cx)
218 {
219         int i, err;
220         CX18_DEBUG_I2C("i2c init\n");
221
222         for (i = 0; i < 2; i++) {
223                 /* Setup algorithm for adapter */
224                 cx->i2c_algo[i] = cx18_i2c_algo_template;
225                 cx->i2c_algo_cb_data[i].cx = cx;
226                 cx->i2c_algo_cb_data[i].bus_index = i;
227                 cx->i2c_algo[i].data = &cx->i2c_algo_cb_data[i];
228
229                 /* Setup adapter */
230                 cx->i2c_adap[i] = cx18_i2c_adap_template;
231                 cx->i2c_adap[i].algo_data = &cx->i2c_algo[i];
232                 sprintf(cx->i2c_adap[i].name + strlen(cx->i2c_adap[i].name),
233                                 " #%d-%d", cx->instance, i);
234                 i2c_set_adapdata(&cx->i2c_adap[i], &cx->v4l2_dev);
235                 cx->i2c_adap[i].dev.parent = &cx->pci_dev->dev;
236         }
237
238         if (cx18_read_reg(cx, CX18_REG_I2C_2_WR) != 0x0003c02f) {
239                 /* Reset/Unreset I2C hardware block */
240                 /* Clock select 220MHz */
241                 cx18_write_reg_expect(cx, 0x10000000, 0xc71004,
242                                           0x00000000, 0x10001000);
243                 /* Clock Enable */
244                 cx18_write_reg_expect(cx, 0x10001000, 0xc71024,
245                                           0x00001000, 0x10001000);
246         }
247         /* courtesy of Steven Toth <stoth@hauppauge.com> */
248         cx18_write_reg_expect(cx, 0x00c00000, 0xc7001c, 0x00000000, 0x00c000c0);
249         mdelay(10);
250         cx18_write_reg_expect(cx, 0x00c000c0, 0xc7001c, 0x000000c0, 0x00c000c0);
251         mdelay(10);
252         cx18_write_reg_expect(cx, 0x00c00000, 0xc7001c, 0x00000000, 0x00c000c0);
253         mdelay(10);
254
255         /* Set to edge-triggered intrs. */
256         cx18_write_reg(cx, 0x00c00000, 0xc730c8);
257         /* Clear any stale intrs */
258         cx18_write_reg_expect(cx, HW2_I2C1_INT|HW2_I2C2_INT, HW2_INT_CLR_STATUS,
259                        ~(HW2_I2C1_INT|HW2_I2C2_INT), HW2_I2C1_INT|HW2_I2C2_INT);
260
261         /* Hw I2C1 Clock Freq ~100kHz */
262         cx18_write_reg(cx, 0x00021c0f & ~4, CX18_REG_I2C_1_WR);
263         cx18_setscl(&cx->i2c_algo_cb_data[0], 1);
264         cx18_setsda(&cx->i2c_algo_cb_data[0], 1);
265
266         /* Hw I2C2 Clock Freq ~100kHz */
267         cx18_write_reg(cx, 0x00021c0f & ~4, CX18_REG_I2C_2_WR);
268         cx18_setscl(&cx->i2c_algo_cb_data[1], 1);
269         cx18_setsda(&cx->i2c_algo_cb_data[1], 1);
270
271         cx18_call_hw(cx, CX18_HW_GPIO_RESET_CTRL,
272                      core, reset, (u32) CX18_GPIO_RESET_I2C);
273
274         err = i2c_bit_add_bus(&cx->i2c_adap[0]);
275         if (err)
276                 goto err;
277         err = i2c_bit_add_bus(&cx->i2c_adap[1]);
278         if (err)
279                 goto err_del_bus_0;
280         return 0;
281
282  err_del_bus_0:
283         i2c_del_adapter(&cx->i2c_adap[0]);
284  err:
285         return err;
286 }
287
288 void exit_cx18_i2c(struct cx18 *cx)
289 {
290         int i;
291         CX18_DEBUG_I2C("i2c exit\n");
292         cx18_write_reg(cx, cx18_read_reg(cx, CX18_REG_I2C_1_WR) | 4,
293                                                         CX18_REG_I2C_1_WR);
294         cx18_write_reg(cx, cx18_read_reg(cx, CX18_REG_I2C_2_WR) | 4,
295                                                         CX18_REG_I2C_2_WR);
296
297         for (i = 0; i < 2; i++) {
298                 i2c_del_adapter(&cx->i2c_adap[i]);
299         }
300 }
301
302 /*
303    Hauppauge HVR1600 should have:
304    32 cx24227
305    98 unknown
306    a0 eeprom
307    c2 tuner
308    e? zilog ir
309    */