xref: /OK3568_Linux_fs/kernel/drivers/media/i2c/techpoint/techpoint_tp9950.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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