1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * techpoint lib
4 *
5 * Copyright (C) 2023 Rockchip Electronics Co., Ltd.
6 */
7
8 #include "techpoint_tp9950.h"
9 #include "techpoint_dev.h"
10
11 static struct techpoint_video_modes supported_modes[] = {
12 #if TP9950_DEF_PAL
13 {
14 .bus_fmt = MEDIA_BUS_FMT_UYVY8_2X8,
15 .width = 960,
16 .height = 576,
17 .max_fps = {
18 .numerator = 10000,
19 .denominator = 250000,
20 },
21 .link_freq_value = TP9950_LINK_FREQ_148M,
22 .common_reg_list = NULL,
23 .common_reg_size = 0,
24 .bpp = TP9950_BITS_PER_SAMPLE,
25 .lane = TP9950_LANES,
26 .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
27 .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_1,
28 .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_2,
29 .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_3,
30 },
31 #endif
32 #if TP9950_DEF_NTSC
33 {
34 .bus_fmt = MEDIA_BUS_FMT_UYVY8_2X8,
35 .width = 960,
36 .height = 480,
37 .max_fps = {
38 .numerator = 10000,
39 .denominator = 250000,
40 },
41 .link_freq_value = TP9950_LINK_FREQ_148M,
42 .common_reg_list = NULL,
43 .common_reg_size = 0,
44 .bpp = TP9950_BITS_PER_SAMPLE,
45 .lane = TP9950_LANES,
46 .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
47 .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_1,
48 .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_2,
49 .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_3,
50 },
51 #endif
52 #if TP9950_DEF_1080P
53 {
54 .bus_fmt = MEDIA_BUS_FMT_UYVY8_2X8,
55 .width = 1920,
56 .height = 1080,
57 .max_fps = {
58 .numerator = 10000,
59 .denominator = 250000,
60 },
61 .link_freq_value = TP9950_LINK_FREQ_594M,
62 .link_freq_value = TP9950_LINK_FREQ_297M,
63 .common_reg_list = NULL,
64 .common_reg_size = 0,
65 .bpp = TP9950_BITS_PER_SAMPLE,
66 .lane = TP9950_LANES,
67 .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
68 .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_1,
69 .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_2,
70 .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_3,
71 },
72 #endif
73 #if TP9950_DEF_720P
74 {
75 .bus_fmt = MEDIA_BUS_FMT_UYVY8_2X8,
76 .width = 1280,
77 .height = 720,
78 .max_fps = {
79 .numerator = 10000,
80 .denominator = 250000,
81 },
82 .link_freq_value = TP9950_LINK_FREQ_297M,
83 .common_reg_list = NULL,
84 .common_reg_size = 0,
85 .bpp = TP9950_BITS_PER_SAMPLE,
86 .lane = TP9950_LANES,
87 .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
88 .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_1,
89 .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_2,
90 .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_3,
91 },
92 #endif
93 };
94
tp9950_initialize(struct techpoint * techpoint)95 int tp9950_initialize(struct techpoint *techpoint)
96 {
97 int array_size = 0;
98 struct i2c_client *client = techpoint->client;
99 struct device *dev = &client->dev;
100
101 techpoint->video_modes_num = ARRAY_SIZE(supported_modes);
102 array_size =
103 sizeof(struct techpoint_video_modes) * techpoint->video_modes_num;
104 techpoint->video_modes = devm_kzalloc(dev, array_size, GFP_KERNEL);
105 memcpy(techpoint->video_modes, supported_modes, array_size);
106
107 techpoint->cur_video_mode = &techpoint->video_modes[0];
108
109 return 0;
110 }
111
tp9950_get_channel_input_status(struct i2c_client * client,u8 ch)112 int tp9950_get_channel_input_status(struct i2c_client *client, u8 ch)
113 {
114 u8 val = 0;
115
116 techpoint_write_reg(client, PAGE_REG, ch);
117 techpoint_read_reg(client, INPUT_STATUS_REG, &val);
118 dev_dbg(&client->dev, "input_status ch %d : %x\n", ch, val);
119
120 return (val & INPUT_STATUS_MASK) ? 0 : 1;
121 }
122
tp9950_get_all_input_status(struct i2c_client * client,u8 * detect_status)123 int tp9950_get_all_input_status(struct i2c_client *client, u8 *detect_status)
124 {
125 u8 val = 0, i;
126
127 for (i = 0; i < PAD_MAX; i++) {
128 techpoint_write_reg(client, PAGE_REG, i);
129 techpoint_read_reg(client, INPUT_STATUS_REG, &val);
130 detect_status[i] = tp9950_get_channel_input_status(client, i);
131 }
132
133 return 0;
134 }
135
tp9950_set_channel_reso(struct i2c_client * client,int ch,enum techpoint_support_reso reso)136 int tp9950_set_channel_reso(struct i2c_client *client, int ch,
137 enum techpoint_support_reso reso)
138 {
139 int val = reso;
140
141 dev_info(&client->dev, "##$$ %s", __func__);
142 techpoint_write_reg(client, 0x41, 0x00);
143 techpoint_write_reg(client, 0x40, 0x08);
144 techpoint_write_reg(client, 0x01, 0xf8);
145 techpoint_write_reg(client, 0x02, 0x01);
146 techpoint_write_reg(client, 0x08, 0x03);
147 techpoint_write_reg(client, 0x20, 0x12);
148 techpoint_write_reg(client, 0x39, 0x00);
149
150 techpoint_write_reg(client, 0x40, 0x00);
151 techpoint_write_reg(client, 0x4c, 0x40);
152 techpoint_write_reg(client, 0x4e, 0x00);
153 techpoint_write_reg(client, 0x27, 0x2d);
154 techpoint_write_reg(client, 0xfd, 0x80);
155
156 switch (val) {
157 case TECHPOINT_S_RESO_720P_25:
158 #if TP9950_DEF_720P
159 default:
160 #endif
161 dev_err(&client->dev, "set channel 720P_25\n");
162 techpoint_write_reg(client, 0x02, 0x42);
163 techpoint_write_reg(client, 0x07, 0xc0);
164 techpoint_write_reg(client, 0x0b, 0xc0);
165 techpoint_write_reg(client, 0x0c, 0x13);
166 techpoint_write_reg(client, 0x0d, 0x50);
167 techpoint_write_reg(client, 0x15, 0x13);
168 techpoint_write_reg(client, 0x16, 0x15);
169 techpoint_write_reg(client, 0x17, 0x00);
170 techpoint_write_reg(client, 0x18, 0x19);
171 techpoint_write_reg(client, 0x19, 0xd0);
172 techpoint_write_reg(client, 0x1a, 0x25);
173 techpoint_write_reg(client, 0x1c, 0x07);//1280*720, 25fps
174 techpoint_write_reg(client, 0x1d, 0xbc);//1280*720, 25fps
175 techpoint_write_reg(client, 0x20, 0x30);
176 techpoint_write_reg(client, 0x21, 0x84);
177 techpoint_write_reg(client, 0x22, 0x36);
178 techpoint_write_reg(client, 0x23, 0x3c);
179 techpoint_write_reg(client, 0x2b, 0x60);
180 techpoint_write_reg(client, 0x2c, 0x0a);
181 techpoint_write_reg(client, 0x2d, 0x30);
182 techpoint_write_reg(client, 0x2e, 0x70);
183 techpoint_write_reg(client, 0x30, 0x48);
184 techpoint_write_reg(client, 0x31, 0xbb);
185 techpoint_write_reg(client, 0x32, 0x2e);
186 techpoint_write_reg(client, 0x33, 0x90);
187 techpoint_write_reg(client, 0x35, 0x25);
188 techpoint_write_reg(client, 0x38, 0x00);
189 techpoint_write_reg(client, 0x39, 0x18);
190 if (STD_HDA) {
191 techpoint_write_reg(client, 0x02, 0x46);
192 techpoint_write_reg(client, 0x0d, 0x71);
193 techpoint_write_reg(client, 0x18, 0x1b);
194 techpoint_write_reg(client, 0x20, 0x40);
195 techpoint_write_reg(client, 0x21, 0x46);
196 techpoint_write_reg(client, 0x25, 0xfe);
197 techpoint_write_reg(client, 0x26, 0x01);
198 techpoint_write_reg(client, 0x2c, 0x3a);
199 techpoint_write_reg(client, 0x2d, 0x5a);
200 techpoint_write_reg(client, 0x2e, 0x40);
201 techpoint_write_reg(client, 0x30, 0x9e);
202 techpoint_write_reg(client, 0x31, 0x20);
203 techpoint_write_reg(client, 0x32, 0x10);
204 techpoint_write_reg(client, 0x33, 0x90);
205 }
206 techpoint_write_reg(client, 0x40, 0x08);
207 techpoint_write_reg(client, 0x23, 0x02);
208 techpoint_write_reg(client, 0x13, 0x24);
209 techpoint_write_reg(client, 0x14, 0x46);
210 techpoint_write_reg(client, 0x15, 0x09);
211 techpoint_write_reg(client, 0x25, 0x08);
212 techpoint_write_reg(client, 0x26, 0x01);
213 techpoint_write_reg(client, 0x27, 0x0e);
214 techpoint_write_reg(client, 0x10, 0x88);
215 techpoint_write_reg(client, 0x10, 0x08);
216 techpoint_write_reg(client, 0x23, 0x00);
217 techpoint_write_reg(client, 0x40, 0x00);
218 break;
219 case TECHPOINT_S_RESO_1080P_25:
220 #if TP9950_DEF_1080P
221 default:
222 #endif
223 dev_err(&client->dev, "set channel 1080P_25\n");
224 techpoint_write_reg(client, 0x02, 0x40);
225 techpoint_write_reg(client, 0x07, 0xc0);
226 techpoint_write_reg(client, 0x0b, 0xc0);
227 techpoint_write_reg(client, 0x0c, 0x03);
228 techpoint_write_reg(client, 0x0d, 0x50);
229 techpoint_write_reg(client, 0x15, 0x03);
230 techpoint_write_reg(client, 0x16, 0xd2);
231 techpoint_write_reg(client, 0x17, 0x80);
232 techpoint_write_reg(client, 0x18, 0x29);
233 techpoint_write_reg(client, 0x19, 0x38);
234 techpoint_write_reg(client, 0x1a, 0x47);
235 techpoint_write_reg(client, 0x1c, 0x0a);//1920*1080, 25fps
236 techpoint_write_reg(client, 0x1d, 0x50);//
237 techpoint_write_reg(client, 0x20, 0x30);
238 techpoint_write_reg(client, 0x21, 0x84);
239 techpoint_write_reg(client, 0x22, 0x36);
240 techpoint_write_reg(client, 0x23, 0x3c);
241 techpoint_write_reg(client, 0x2b, 0x60);
242 techpoint_write_reg(client, 0x2c, 0x0a);
243 techpoint_write_reg(client, 0x2d, 0x30);
244 techpoint_write_reg(client, 0x2e, 0x70);
245 techpoint_write_reg(client, 0x30, 0x48);
246 techpoint_write_reg(client, 0x31, 0xbb);
247 techpoint_write_reg(client, 0x32, 0x2e);
248 techpoint_write_reg(client, 0x33, 0x90);
249 techpoint_write_reg(client, 0x35, 0x05);
250 techpoint_write_reg(client, 0x38, 0x00);
251 techpoint_write_reg(client, 0x39, 0x1C);
252 if (STD_HDA) {
253 techpoint_write_reg(client, 0x02, 0x44);
254 techpoint_write_reg(client, 0x0d, 0x73);
255 techpoint_write_reg(client, 0x15, 0x01);
256 techpoint_write_reg(client, 0x16, 0xf0);
257 techpoint_write_reg(client, 0x18, 0x2a);
258 techpoint_write_reg(client, 0x20, 0x3c);
259 techpoint_write_reg(client, 0x21, 0x46);
260 techpoint_write_reg(client, 0x25, 0xfe);
261 techpoint_write_reg(client, 0x26, 0x0d);
262 techpoint_write_reg(client, 0x2c, 0x3a);
263 techpoint_write_reg(client, 0x2d, 0x54);
264 techpoint_write_reg(client, 0x2e, 0x40);
265 techpoint_write_reg(client, 0x30, 0xa5);
266 techpoint_write_reg(client, 0x31, 0x86);
267 techpoint_write_reg(client, 0x32, 0xfb);
268 techpoint_write_reg(client, 0x33, 0x60);
269 }
270 techpoint_write_reg(client, 0x40, 0x08);
271 techpoint_write_reg(client, 0x23, 0x02);
272 techpoint_write_reg(client, 0x13, 0x04);
273 techpoint_write_reg(client, 0x14, 0x46);
274 techpoint_write_reg(client, 0x15, 0x09);
275 techpoint_write_reg(client, 0x25, 0x08);
276 techpoint_write_reg(client, 0x26, 0x04);
277 techpoint_write_reg(client, 0x27, 0x0c);
278 techpoint_write_reg(client, 0x10, 0x88);
279 techpoint_write_reg(client, 0x10, 0x08);
280 techpoint_write_reg(client, 0x23, 0x00);
281 techpoint_write_reg(client, 0x40, 0x00);
282 /* techpoint_write_reg(client, 0x41, 0xc0); */
283 break;
284 case TECHPOINT_S_RESO_PAL:
285 #if TP9950_DEF_PAL
286 default:
287 #endif
288 dev_err(&client->dev, "set channel PAL\n");
289 techpoint_write_reg(client, 0x02, 0x47);
290 techpoint_write_reg(client, 0x07, 0x80);
291 techpoint_write_reg(client, 0x0b, 0x80);
292 techpoint_write_reg(client, 0x0c, 0x13);
293 techpoint_write_reg(client, 0x0d, 0x51);
294 techpoint_write_reg(client, 0x15, 0x13);
295 techpoint_write_reg(client, 0x16, 0x76);
296 techpoint_write_reg(client, 0x17, 0x80);
297 techpoint_write_reg(client, 0x18, 0x17);
298 techpoint_write_reg(client, 0x19, 0x20);
299 techpoint_write_reg(client, 0x1a, 0x17);
300 techpoint_write_reg(client, 0x1c, 0x09);
301 techpoint_write_reg(client, 0x1d, 0x48);
302 techpoint_write_reg(client, 0x20, 0x48);
303 techpoint_write_reg(client, 0x21, 0x84);
304 techpoint_write_reg(client, 0x22, 0x37);
305 techpoint_write_reg(client, 0x23, 0x3f);
306 techpoint_write_reg(client, 0x2b, 0x70);
307 techpoint_write_reg(client, 0x2c, 0x2a);
308 techpoint_write_reg(client, 0x2d, 0x64);
309 techpoint_write_reg(client, 0x2e, 0x56);
310 techpoint_write_reg(client, 0x30, 0x7a);
311 techpoint_write_reg(client, 0x31, 0x4a);
312 techpoint_write_reg(client, 0x32, 0x4d);
313 techpoint_write_reg(client, 0x33, 0xf0);
314 techpoint_write_reg(client, 0x35, 0x65);
315 techpoint_write_reg(client, 0x38, 0x00);
316 techpoint_write_reg(client, 0x39, 0x04);
317 techpoint_write_reg(client, 0x40, 0x08);
318 techpoint_write_reg(client, 0x23, 0x02);
319 techpoint_write_reg(client, 0x13, 0x24);
320 techpoint_write_reg(client, 0x14, 0x57);
321 techpoint_write_reg(client, 0x15, 0x0e);
322 techpoint_write_reg(client, 0x25, 0x02);
323 techpoint_write_reg(client, 0x26, 0x00);
324 techpoint_write_reg(client, 0x27, 0x03);
325 techpoint_write_reg(client, 0x10, 0x88);
326 techpoint_write_reg(client, 0x10, 0x08);
327 techpoint_write_reg(client, 0x23, 0x00);
328 techpoint_write_reg(client, 0x40, 0x00);
329 break;
330 case TECHPOINT_S_RESO_NTSC:
331 #if TP9950_DEF_NTSC
332 default:
333 #endif
334 dev_err(&client->dev, "set channel NTSC\n");
335 techpoint_write_reg(client, 0x02, 0x47);
336 techpoint_write_reg(client, 0x07, 0x80);
337 techpoint_write_reg(client, 0x0b, 0x80);
338 techpoint_write_reg(client, 0x0c, 0x13);
339 techpoint_write_reg(client, 0x0d, 0x50);
340
341 techpoint_write_reg(client, 0x15, 0x13);
342 techpoint_write_reg(client, 0x16, 0x60);
343 techpoint_write_reg(client, 0x17, 0x80);
344 techpoint_write_reg(client, 0x18, 0x12);
345 techpoint_write_reg(client, 0x19, 0xf0);
346 techpoint_write_reg(client, 0x1a, 0x07);
347 techpoint_write_reg(client, 0x1c, 0x09);
348 techpoint_write_reg(client, 0x1d, 0x38);
349
350 techpoint_write_reg(client, 0x20, 0x40);
351 techpoint_write_reg(client, 0x21, 0x84);
352 techpoint_write_reg(client, 0x22, 0x36);
353 techpoint_write_reg(client, 0x23, 0x3c);
354
355 techpoint_write_reg(client, 0x2b, 0x70);
356 techpoint_write_reg(client, 0x2c, 0x2a);
357 techpoint_write_reg(client, 0x2d, 0x68);
358 techpoint_write_reg(client, 0x2e, 0x57);
359
360 techpoint_write_reg(client, 0x30, 0x62);
361 techpoint_write_reg(client, 0x31, 0xbb);
362 techpoint_write_reg(client, 0x32, 0x96);
363 techpoint_write_reg(client, 0x33, 0xc0);
364
365 techpoint_write_reg(client, 0x35, 0x65);
366 techpoint_write_reg(client, 0x38, 0x00);
367 techpoint_write_reg(client, 0x39, 0x04);
368
369 techpoint_write_reg(client, 0x40, 0x08);
370 techpoint_write_reg(client, 0x23, 0x02);
371 techpoint_write_reg(client, 0x13, 0x24);
372 techpoint_write_reg(client, 0x14, 0x57);
373 techpoint_write_reg(client, 0x15, 0x0e);
374
375 techpoint_write_reg(client, 0x25, 0x02);
376 techpoint_write_reg(client, 0x26, 0x00);
377 techpoint_write_reg(client, 0x27, 0x03);
378
379 techpoint_write_reg(client, 0x10, 0x88);
380 techpoint_write_reg(client, 0x10, 0x08);
381 techpoint_write_reg(client, 0x23, 0x00);
382 techpoint_write_reg(client, 0x40, 0x00);
383 break;
384 }
385
386 #if TECHPOINT_TEST_PATTERN
387 techpoint_write_reg(client, 0x2a, 0x3c);
388 #endif
389
390 return 0;
391 }
392
tp9950_get_channel_reso(struct i2c_client * client,int ch)393 int tp9950_get_channel_reso(struct i2c_client *client, int ch)
394 {
395 u8 detect_fmt = 0xff;
396 u8 reso = 0xff;
397
398 techpoint_write_reg(client, 0x40, ch);
399 techpoint_read_reg(client, 0x03, &detect_fmt);
400 reso = detect_fmt & 0x7;
401
402 switch (reso) {
403 case TP9950_CVSTD_720P_25:
404 #if TP9950_DEF_720P
405 default:
406 #endif
407 dev_err(&client->dev, "detect channel %d 720P_25\n", ch);
408 return TECHPOINT_S_RESO_720P_25;
409 case TP9950_CVSTD_1080P_25:
410 #if TP9950_DEF_1080P
411 default:
412 #endif
413 dev_err(&client->dev, "detect channel %d 1080P_25\n", ch);
414 return TECHPOINT_S_RESO_1080P_25;
415 case TP9950_CVSTD_PAL:
416 #if TP9950_DEF_PAL
417 default:
418 #endif
419 dev_err(&client->dev, "detect channel %d PAL\n", ch);
420 return TECHPOINT_S_RESO_PAL;
421 case TP9950_CVSTD_NTSC:
422 #if TP9950_DEF_NTSC
423 default:
424 #endif
425 dev_err(&client->dev, "detect channel %d NTSC\n", ch);
426 return TECHPOINT_S_RESO_NTSC;
427 }
428
429 return reso;
430 }
431
tp9950_set_quick_stream(struct i2c_client * client,u32 stream)432 int tp9950_set_quick_stream(struct i2c_client *client, u32 stream)
433 {
434 return 0;
435 }
436