xref: /OK3568_Linux_fs/kernel/drivers/media/spi/rk1608_dev.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: GPL-2.0
2 /**
3  * Rockchip rk1608 device driver
4  *
5  * Copyright (C) Rockchip Electronics Co., Ltd.
6  *
7  */
8 #include <linux/of_platform.h>
9 #include <linux/ctype.h>
10 #include <media/v4l2-ctrls.h>
11 #include <media/v4l2-fwnode.h>
12 #include <media/v4l2-subdev.h>
13 #include <linux/compat.h>
14 #include <linux/rk-preisp.h>
15 #include "rk1608_dev.h"
16 
17 #define DEBUG_DUMP_ALL_SEND_RECV_MSG 0
18 
19 #define MSG_QUEUE_DEFAULT_SIZE (8 * 1024)
20 
21 struct msg_queue {
22 	u32 *buf_head; /* msg buffer head */
23 	u32 *buf_tail; /* msg buffer tail */
24 	u32 *cur_send; /* current msg send position */
25 	u32 *cur_recv; /* current msg receive position */
26 };
27 
28 struct rk1608_client {
29 	s8 id;
30 	struct msg_queue q;
31 	struct list_head list;
32 	wait_queue_head_t wait;
33 	void *private_data;
34 };
35 
36 enum {
37 	AUTO_ARG_TYPE_STR,
38 	AUTO_ARG_TYPE_INT32,
39 };
40 
41 struct auto_arg {
42 	int type;
43 	union {
44 		s32 m_int32;
45 		const char *m_str;
46 	};
47 };
48 
49 struct auto_args {
50 	int argc;
51 	struct auto_arg *argv;
52 };
53 
54 /**
55  * msq_init - Initialize msg queue
56  *
57  * @q: the msg queue to initialize
58  * @size: size of msg queue buf
59  *
60  * It returns zero on success, else a negative error code.
61  */
msq_init(struct msg_queue * q,int size)62 static int msq_init(struct msg_queue *q, int size)
63 {
64 	u32 *buf = kmalloc(size, GFP_KERNEL);
65 
66 	q->buf_head = buf;
67 	q->buf_tail = buf + size / sizeof(u32);
68 	q->cur_send = buf;
69 	q->cur_recv = buf;
70 
71 	return 0;
72 }
73 
74 /**
75  * msq_release - release msg queue buf
76  *
77  * @q: the msg queue to release
78  */
msq_release(struct msg_queue * q)79 static void msq_release(struct msg_queue *q)
80 {
81 	kfree(q->buf_head);
82 	q->buf_head = NULL;
83 	q->buf_tail = NULL;
84 	q->cur_send = NULL;
85 	q->cur_recv = NULL;
86 }
87 
88 /**
89  * msq_is_empty - tests whether a msg queue is empty
90  *
91  * @q: the msg queue to test
92  *
93  * It returns true on msg queue is empty, else false.
94  */
msq_is_empty(const struct msg_queue * q)95 static int msq_is_empty(const struct msg_queue *q)
96 {
97 	return q->cur_send == q->cur_recv;
98 }
99 
100 /**
101  * msq_tail_free_size - get msg queue tail unused buf size
102  *
103  * @q: msg queue
104  *
105  * It returns size of msg queue tail unused buf size, unit 4 bytes
106  */
msq_tail_free_size(const struct msg_queue * q)107 static u32 msq_tail_free_size(const struct msg_queue *q)
108 {
109 	if (q->cur_send >= q->cur_recv)
110 		return (q->buf_tail - q->cur_send);
111 
112 	return q->cur_recv - q->cur_send;
113 }
114 
115 /**
116  * msq_head_free_size - get msg queue head unused buf size
117  *
118  * @q: msg queue
119  *
120  * It returns size of msg queue head unused buf size, unit 4 bytes
121  */
msq_head_free_size(const struct msg_queue * q)122 static u32 msq_head_free_size(const struct msg_queue *q)
123 {
124 	if (q->cur_send >= q->cur_recv)
125 		return (q->cur_recv - q->buf_head);
126 
127 	return 0;
128 }
129 
130 /**
131  * msq_send_msg - send a msg to msg queue
132  *
133  * @q: msg queue
134  * @m: a msg to queue
135  *
136  * It returns zero on success, else a negative error code.
137  */
msq_send_msg(struct msg_queue * q,const struct msg * m)138 static int msq_send_msg(struct msg_queue *q, const struct msg *m)
139 {
140 	int ret = 0;
141 
142 	if (msq_tail_free_size(q) > m->size) {
143 		u32 *next_send;
144 
145 		memcpy(q->cur_send, m, m->size * sizeof(u32));
146 		next_send = q->cur_send + m->size;
147 		if (next_send == q->buf_tail)
148 			next_send = q->buf_head;
149 
150 		q->cur_send = next_send;
151 	} else if (msq_head_free_size(q) > m->size) {
152 		*q->cur_send = 0; /* set size to 0 for skip to head mark */
153 		memcpy(q->buf_head, m, m->size * sizeof(u32));
154 		q->cur_send = q->buf_head + m->size;
155 	} else {
156 		ret = -1;
157 	}
158 
159 	return ret;
160 }
161 
162 /**
163  * msq_recv_msg - receive a msg from msg queue
164  *
165  * @q: msg queue
166  * @m: a msg pointer buf [out]
167  *
168  * need call msq_recv_msg_free to free msg after msg use done
169  *
170  * It returns zero on success, else a negative error code.
171  */
msq_recv_msg(struct msg_queue * q,struct msg ** m)172 static int msq_recv_msg(struct msg_queue *q, struct msg **m)
173 {
174 	*m = NULL;
175 	if (msq_is_empty(q))
176 		return -1;
177 
178 	/* skip to head when size is 0 */
179 	if (*q->cur_recv == 0)
180 		*m = (struct msg *)q->buf_head;
181 	else
182 		*m = (struct msg *)q->cur_recv;
183 
184 	return 0;
185 }
186 
187 /**
188  * msq_free_received_msg - free a received msg to msg queue
189  *
190  * @q: msg queue
191  * @m: a msg
192  *
193  * It returns zero on success, else a negative error code.
194  */
msq_free_received_msg(struct msg_queue * q,const struct msg * m)195 static int msq_free_received_msg(struct msg_queue *q, const struct msg *m)
196 {
197 	/* skip to head when size is 0 */
198 	if (*q->cur_recv == 0) {
199 		q->cur_recv = q->buf_head + m->size;
200 	} else {
201 		u32 *next_recv;
202 
203 		next_recv = q->cur_recv + m->size;
204 		if (next_recv == q->buf_tail)
205 			next_recv = q->buf_head;
206 
207 		q->cur_recv = next_recv;
208 	}
209 
210 	return 0;
211 }
212 
rk1608_client_list_init(struct rk1608_client_list * s)213 static void rk1608_client_list_init(struct rk1608_client_list *s)
214 {
215 	mutex_init(&s->mutex);
216 	INIT_LIST_HEAD(&s->list);
217 }
218 
rk1608_client_new(void)219 static struct rk1608_client *rk1608_client_new(void)
220 {
221 	struct rk1608_client *c = kzalloc(sizeof(*c), GFP_KERNEL);
222 
223 	if (!c)
224 		return NULL;
225 
226 	c->id = INVALID_ID;
227 	INIT_LIST_HEAD(&c->list);
228 	msq_init(&c->q, MSG_QUEUE_DEFAULT_SIZE);
229 	init_waitqueue_head(&c->wait);
230 
231 	return c;
232 }
233 
rk1608_client_release(struct rk1608_client * c)234 static void rk1608_client_release(struct rk1608_client *c)
235 {
236 	msq_release(&c->q);
237 	kfree(c);
238 }
239 
240 static struct rk1608_client *
rk1608_client_find(struct rk1608_client_list * s,struct rk1608_client * c)241 rk1608_client_find(struct rk1608_client_list *s,
242 		   struct rk1608_client *c)
243 {
244 	struct rk1608_client *client = NULL;
245 
246 	list_for_each_entry(client, &s->list, list) {
247 		if (c == client)
248 			return c;
249 	}
250 
251 	return NULL;
252 }
253 
rk1608_client_connect(struct rk1608_state * pdata,struct rk1608_client * c)254 static int rk1608_client_connect(struct rk1608_state *pdata,
255 				 struct rk1608_client *c)
256 {
257 	struct rk1608_client_list *s = &pdata->clients;
258 
259 	mutex_lock(&s->mutex);
260 	if (rk1608_client_find(s, c)) {
261 		mutex_unlock(&s->mutex);
262 		return -1;
263 	}
264 
265 	list_add_tail(&c->list, &s->list);
266 	mutex_unlock(&s->mutex);
267 
268 	return 0;
269 }
270 
rk1608_client_disconnect(struct rk1608_state * pdata,struct rk1608_client * c)271 static void rk1608_client_disconnect(struct rk1608_state *pdata,
272 				     struct rk1608_client *c)
273 {
274 	struct rk1608_client_list *s = &pdata->clients;
275 
276 	mutex_lock(&s->mutex);
277 	if (rk1608_client_find(s, c))
278 		list_del_init(&c->list);
279 	mutex_unlock(&s->mutex);
280 }
281 
parse_arg(const char * s,struct auto_arg * arg)282 static int parse_arg(const char *s, struct auto_arg *arg)
283 {
284 	if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) {
285 		long v;
286 
287 		v = simple_strtol(s, NULL, 16);
288 		arg->type = AUTO_ARG_TYPE_INT32;
289 		arg->m_int32 = v;
290 	} else if (isdigit(s[0])) {
291 		long v;
292 
293 		v = simple_strtol(s, NULL, 10);
294 		arg->type = AUTO_ARG_TYPE_INT32;
295 		arg->m_int32 = v;
296 	} else {
297 		arg->type = AUTO_ARG_TYPE_STR;
298 		arg->m_str = s;
299 	}
300 
301 	return 0;
302 }
303 
parse_auto_args(char * s,struct auto_args * args)304 static int parse_auto_args(char *s, struct auto_args *args)
305 {
306 	int i = 0;
307 	char c = 0;
308 	int last_is_arg_flag = 0;
309 	const char *last_arg;
310 
311 	args->argc = 0;
312 
313 	i = -1;
314 	do {
315 		c = s[++i];
316 		if (c == ' ' || c == ',' || c == '\n' || c == '\r' || c == 0) {
317 			if (last_is_arg_flag)
318 				args->argc++;
319 
320 			last_is_arg_flag = 0;
321 		} else {
322 			last_is_arg_flag = 1;
323 		}
324 	} while (c != 0 && c != '\n' && c != '\r');
325 
326 	args->argv =
327 		kmalloc_array(args->argc, sizeof(struct auto_arg), GFP_KERNEL);
328 	if (!args->argv)
329 		return -ENOMEM;
330 
331 	i = -1;
332 	last_is_arg_flag = 0;
333 	last_arg = s;
334 	args->argc = 0;
335 	do {
336 		c = s[++i];
337 		if (c == ' ' || c == ',' || c == '\n' || c == '\r' || c == 0) {
338 			if (last_is_arg_flag) {
339 				parse_arg(last_arg, args->argv + args->argc++);
340 				s[i] = 0;
341 			}
342 			last_is_arg_flag = 0;
343 		} else {
344 			if (last_is_arg_flag == 0)
345 				last_arg = s + i;
346 
347 			last_is_arg_flag = 1;
348 		}
349 	} while (c != 0 && c != '\n' && c != '\r');
350 
351 	return c == 0 ? i : i + 1;
352 }
353 
free_auto_args(struct auto_args * args)354 static void free_auto_args(struct auto_args *args)
355 {
356 	kfree(args->argv);
357 	args->argv = NULL;
358 	args->argc = 0;
359 }
360 
int32_hexdump(const char * prefix,s32 * data,int len)361 static void int32_hexdump(const char *prefix, s32 *data, int len)
362 {
363 	pr_err("%s\n", prefix);
364 	print_hex_dump(KERN_ERR, "offset ", DUMP_PREFIX_OFFSET,
365 		       16, 4, data, len, false);
366 	pr_err("\n");
367 }
368 
do_cmd_write(struct rk1608_state * pdata,const struct auto_args * args)369 static int do_cmd_write(struct rk1608_state *pdata,
370 			const struct auto_args *args)
371 {
372 	s32 addr;
373 	s32 len = (args->argc - 2) * sizeof(s32);
374 	s32 *data;
375 	int i;
376 
377 	if (args->argc < 3 || args->argv[1].type != AUTO_ARG_TYPE_INT32) {
378 		dev_err(pdata->dev, "Mis or unknown args!\n");
379 		return -1;
380 	}
381 
382 	len = MIN(len, RK1608_MAX_OP_BYTES);
383 
384 	addr = args->argv[1].m_int32;
385 	data = kmalloc(len, GFP_KERNEL);
386 	if (!data)
387 		return -ENOMEM;
388 
389 	for (i = 0; i < len / 4; i++) {
390 		if (args->argv[i + 2].type != AUTO_ARG_TYPE_INT32) {
391 			dev_err(pdata->dev, "Unknown args!\n");
392 			kfree(data);
393 			return -1;
394 		}
395 
396 		data[i] = args->argv[i + 2].m_int32;
397 	}
398 
399 	rk1608_write(pdata->spi, addr, data, len);
400 
401 	kfree(data);
402 
403 	dev_info(pdata->dev, "write addr: 0x%x, len: %d bytes\n", addr, len);
404 	return 0;
405 }
406 
do_cmd_read(struct rk1608_state * pdata,const struct auto_args * args)407 static int do_cmd_read(struct rk1608_state *pdata,
408 		       const struct auto_args *args)
409 {
410 	s32 addr;
411 	s32 len;
412 	s32 *data;
413 
414 	if (args->argc < 3 || args->argv[1].type != AUTO_ARG_TYPE_INT32) {
415 		dev_err(pdata->dev, "Mis or unknown args!\n");
416 		return -1;
417 	}
418 
419 	addr = args->argv[1].m_int32;
420 	if (args->argc == 2) {
421 		len = 32;
422 	} else {
423 		if (args->argv[2].type != AUTO_ARG_TYPE_INT32) {
424 			dev_err(pdata->dev, "Unknown args!\n");
425 			return -1;
426 		}
427 		len = args->argv[2].m_int32 * sizeof(s32);
428 		len = MIN(len, RK1608_MAX_OP_BYTES);
429 	}
430 
431 	data = kmalloc(len, GFP_KERNEL);
432 	if (!data)
433 		return -ENOMEM;
434 
435 	dev_info(pdata->dev, "\nread addr: %x, len: %d bytes\n", addr, len);
436 	rk1608_read(pdata->spi, addr, data, len);
437 	int32_hexdump("read data:", data, len);
438 	kfree(data);
439 
440 	return 0;
441 }
442 
do_cmd_set_spi_rate(struct rk1608_state * pdata,const struct auto_args * args)443 static int do_cmd_set_spi_rate(struct rk1608_state *pdata,
444 			       const struct auto_args *args)
445 {
446 	if (args->argc < 2 || args->argv[1].type != AUTO_ARG_TYPE_INT32) {
447 		dev_err(pdata->dev, "Mis or unknown args!\n");
448 		return -1;
449 	}
450 
451 	pdata->max_speed_hz = args->argv[1].m_int32;
452 	dev_info(pdata->dev, "set spi max speed to %d!\n", pdata->max_speed_hz);
453 
454 	if (args->argc == 3 && args->argv[2].type == AUTO_ARG_TYPE_INT32) {
455 		pdata->min_speed_hz = args->argv[2].m_int32;
456 		dev_info(pdata->dev, "set spi min speed to %d!\n",
457 			 pdata->min_speed_hz);
458 	}
459 
460 	return 0;
461 }
462 
do_cmd_query(struct rk1608_state * pdata,const struct auto_args * args)463 static int do_cmd_query(struct rk1608_state *pdata,
464 			const struct auto_args *args)
465 {
466 	s32 state;
467 
468 	rk1608_operation_query(pdata->spi, &state);
469 	dev_info(pdata->dev, "state %x\n", state);
470 	return 0;
471 }
472 
do_cmd_download_fw(struct rk1608_state * pdata,const struct auto_args * args)473 static int do_cmd_download_fw(struct rk1608_state *pdata,
474 			      const struct auto_args *args)
475 {
476 	int ret = 0;
477 	const char *fw_name = NULL;
478 
479 	if (args->argc == 2 && args->argv[1].type == AUTO_ARG_TYPE_STR)
480 		fw_name = args->argv[1].m_str;
481 
482 	ret = rk1608_download_fw(pdata, pdata->spi, fw_name);
483 	if (ret)
484 		dev_err(pdata->dev, "download firmware failed!\n");
485 	else
486 		dev_info(pdata->dev, "download firmware success!\n");
487 
488 	return 0;
489 }
490 
do_cmd_fast_write(struct rk1608_state * pdata,const struct auto_args * args)491 static int do_cmd_fast_write(struct rk1608_state *pdata,
492 			     const struct auto_args *args)
493 {
494 	int ret = 0;
495 	s32 reg;
496 
497 	if (args->argc != 2 || args->argv[1].type != AUTO_ARG_TYPE_INT32) {
498 		dev_err(pdata->dev, "Mis or unknown args!\n");
499 		return -1;
500 	}
501 
502 	reg = args->argv[1].m_int32;
503 
504 	ret = rk1608_interrupt_request(pdata->spi, reg);
505 	dev_info(pdata->dev, "interrupt request reg1:%x ret:%x\n", reg, ret);
506 
507 	return 0;
508 }
509 
do_cmd_fast_read(struct rk1608_state * pdata,const struct auto_args * args)510 static int do_cmd_fast_read(struct rk1608_state *pdata,
511 			    const struct auto_args *args)
512 {
513 	s32 state;
514 
515 	rk1608_state_query(pdata->spi, &state);
516 	dev_info(pdata->dev, "dsp state %x\n", state);
517 
518 	return 0;
519 }
520 
do_cmd_send_msg(struct rk1608_state * pdata,const struct auto_args * args)521 static int do_cmd_send_msg(struct rk1608_state *pdata,
522 			   const struct auto_args *args)
523 {
524 	struct msg *m;
525 	int ret = 0;
526 	int msg_len;
527 	u32 i = 0;
528 
529 	if (args->argc < 2) {
530 		dev_err(pdata->dev, "need more args\n");
531 		return -1;
532 	}
533 
534 	msg_len = args->argc * sizeof(u32);
535 
536 	m = kmalloc(msg_len, GFP_KERNEL);
537 	if (!m)
538 		return -ENOMEM;
539 
540 	m->size = msg_len / 4;
541 	for (i = 1; i < m->size; i++) {
542 		if (args->argv[i].type != AUTO_ARG_TYPE_INT32) {
543 			dev_err(pdata->dev, "Unknown args!\n");
544 			kfree(m);
545 			return -1;
546 		}
547 
548 		*((s32 *)m + i) = args->argv[i].m_int32;
549 	}
550 
551 	ret = rk1608_send_msg_to_dsp(pdata, m);
552 
553 	dev_info(pdata->dev, "send msg len: %d, ret: %x\n", m->size, ret);
554 
555 	kfree(m);
556 
557 	return 0;
558 }
559 
do_cmd_recv_msg(struct rk1608_state * pdata,const struct auto_args * args)560 static int do_cmd_recv_msg(struct rk1608_state *pdata,
561 			   const struct auto_args *args)
562 {
563 	struct msg *m;
564 	char buf[256] = "";
565 	int ret = 0;
566 
567 	ret = rk1608_msq_recv_msg(pdata, pdata->spi, &m);
568 	if (ret || !m)
569 		return 0;
570 
571 	dev_info(pdata->dev, "\nrecv msg len: %d, ret: %x\n", m->size, ret);
572 	int32_hexdump("recv msg:", (s32 *)m, m->size * 4);
573 
574 	dev_info(pdata->dev, buf);
575 
576 	kfree(m);
577 
578 	return 0;
579 }
580 
do_cmd_power_on(struct rk1608_state * pdata,const struct auto_args * args)581 static int do_cmd_power_on(struct rk1608_state *pdata,
582 			   const struct auto_args *args)
583 {
584 	int ret;
585 
586 	ret = rk1608_set_power(pdata, 1);
587 	dev_info(pdata->dev, "do cmd power on, count++\n");
588 
589 	return ret;
590 }
591 
do_cmd_power_off(struct rk1608_state * pdata,const struct auto_args * args)592 static int do_cmd_power_off(struct rk1608_state *pdata,
593 			    const struct auto_args *args)
594 {
595 	int ret;
596 
597 	ret = rk1608_set_power(pdata, 0);
598 	dev_info(pdata->dev, "do cmd power off, count--\n");
599 
600 	return ret;
601 }
602 
do_cmd_set_dsp_log_level(struct rk1608_state * pdata,const struct auto_args * args)603 static int do_cmd_set_dsp_log_level(struct rk1608_state *pdata,
604 				    const struct auto_args *args)
605 {
606 	int ret;
607 
608 	if (args->argc != 2 || args->argv[1].type != AUTO_ARG_TYPE_INT32) {
609 		dev_err(pdata->dev, "Mis or unknown args!\n");
610 		return -1;
611 	}
612 
613 	pdata->log_level = args->argv[1].m_int32;
614 	ret = rk1608_set_log_level(pdata, pdata->log_level);
615 
616 	dev_info(pdata->dev, "set dsp log level %d, ret: %d\n",
617 		 pdata->log_level, ret);
618 
619 	return ret;
620 }
621 
do_cmd_version(struct rk1608_state * pdata,const struct auto_args * args)622 static int do_cmd_version(struct rk1608_state *pdata,
623 			  const struct auto_args *args)
624 {
625 	dev_info(pdata->dev, "driver version: v%02x.%02x.%02x\n",
626 		 RK1608_VERSION >> 16,
627 		 (RK1608_VERSION & 0xff00) >> 8,
628 		 RK1608_VERSION & 0x00ff);
629 	return 0;
630 }
631 
do_cmd_help(struct rk1608_state * pdata)632 static int do_cmd_help(struct rk1608_state *pdata)
633 {
634 	dev_info(pdata->dev, "\n"
635 		 "support debug commands:\n"
636 		 "v            -- rk1608 driver version.\n"
637 		 "log level    -- set rk1608 log level.\n"
638 		 "on           -- power count + 1.\n"
639 		 "off          -- power count - 1.\n"
640 		 "f [fw_name]  -- download fw.\n"
641 		 "q            -- query operation status.\n"
642 		 "r addr [length=32] -- read addr.\n"
643 		 "w addr value,...   -- write addr.\n"
644 		 "s type,...         -- send msg.\n"
645 		 "rate max [min]     -- set spi speed.\n\n");
646 	return 0;
647 }
648 
do_cmd(struct rk1608_state * pdata,const struct auto_args * args)649 static int do_cmd(struct rk1608_state *pdata, const struct auto_args *args)
650 {
651 	const char *s;
652 
653 	if (args->argv->type != AUTO_ARG_TYPE_STR)
654 		return 0;
655 
656 	s = args->argv->m_str;
657 	/* echo c > /dev/rk_preisp */
658 	if (!strcmp(s, "c"))
659 		return do_cmd_recv_msg(pdata, args);
660 	/* echo f [fw_name] > /dev/rk_preisp */
661 	if (!strcmp(s, "f"))
662 		return do_cmd_download_fw(pdata, args);
663 	/* echo fw reg1 > /dev/rk_preisp */
664 	if (!strcmp(s, "fw"))
665 		return do_cmd_fast_write(pdata, args);
666 	/* echo fr > /dev/rk_preisp */
667 	if (!strcmp(s, "fr"))
668 		return do_cmd_fast_read(pdata, args);
669 	/* echo log level > /dev/rk_preisp */
670 	if (!strcmp(s, "log"))
671 		return do_cmd_set_dsp_log_level(pdata, args);
672 	/* echo on > /dev/rk_preisp */
673 	if (!strcmp(s, "on"))
674 		return do_cmd_power_on(pdata, args);
675 	/* echo off > /dev/rk_preisp */
676 	if (!strcmp(s, "off"))
677 		return do_cmd_power_off(pdata, args);
678 	/* echo q > /dev/rk_preisp */
679 	if (!strcmp(s, "q"))
680 		return do_cmd_query(pdata, args);
681 	/* echo r addr [length] > /dev/rk_preisp */
682 	if (!strcmp(s, "r"))
683 		return do_cmd_read(pdata, args);
684 	/* echo rate > /dev/rk_preisp */
685 	if (!strcmp(s, "rate"))
686 		return do_cmd_set_spi_rate(pdata, args);
687 	/* echo s type,... > /dev/rk_preisp */
688 	if (!strcmp(s, "s"))
689 		return do_cmd_send_msg(pdata, args);
690 	/* echo v > /dev/rk_preisp */
691 	if (!strcmp(s, "v"))
692 		return do_cmd_version(pdata, args);
693 	/* echo w addr value,... > /dev/rk_preisp */
694 	if (!strcmp(s, "w"))
695 		return do_cmd_write(pdata, args);
696 
697 	dev_err(pdata->dev, "unknown commands:%s\n", s);
698 	do_cmd_help(pdata);
699 
700 	return 0;
701 }
702 
rk1608_dev_open(struct inode * inode,struct file * file)703 static int rk1608_dev_open(struct inode *inode, struct file *file)
704 {
705 	struct rk1608_state *pdata =
706 		container_of(file->private_data, struct rk1608_state, misc);
707 	struct rk1608_client *client = rk1608_client_new();
708 
709 	client->private_data = pdata;
710 	file->private_data = client;
711 
712 	rk1608_set_power(pdata, 1);
713 
714 	return 0;
715 }
716 
rk1608_dev_release(struct inode * inode,struct file * file)717 static int rk1608_dev_release(struct inode *inode, struct file *file)
718 {
719 	struct rk1608_client *client = file->private_data;
720 	struct rk1608_state *pdata = client->private_data;
721 
722 	rk1608_client_disconnect(pdata, client);
723 	rk1608_client_release(client);
724 	rk1608_set_power(pdata, 0);
725 
726 	return 0;
727 }
728 
rk1608_dev_write(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)729 static ssize_t rk1608_dev_write(struct file *file, const char __user *user_buf,
730 				size_t count, loff_t *ppos)
731 {
732 	char *buf;
733 	struct auto_args args;
734 	int i;
735 	struct rk1608_client *client = file->private_data;
736 	struct rk1608_state *pdata = client->private_data;
737 
738 	buf = kmalloc(count + 1, GFP_KERNEL);
739 	if (!buf)
740 		return -ENOMEM;
741 
742 	if (copy_from_user(buf, user_buf, count))
743 		return -EFAULT;
744 
745 	buf[count] = 0;
746 
747 	i = 0;
748 	while (buf[i] != 0) {
749 		int ret = parse_auto_args(buf + i, &args);
750 
751 		if (ret < 0)
752 			break;
753 
754 		i += ret;
755 		if (args.argc == 0)
756 			continue;
757 
758 		do_cmd(pdata, &args);
759 		free_auto_args(&args);
760 	}
761 
762 	kfree(buf);
763 
764 	return count;
765 }
766 
rk1608_dev_ioctl(struct file * file,unsigned int cmd,unsigned long arg)767 static long rk1608_dev_ioctl(struct file *file, unsigned int cmd,
768 			     unsigned long arg)
769 {
770 	int ret = 0;
771 	void __user *ubuf = (void __user *)arg;
772 	struct rk1608_client *client = file->private_data;
773 	struct rk1608_state *pdata = client->private_data;
774 
775 	switch (cmd) {
776 	case PREISP_POWER_ON:
777 		ret = rk1608_set_power(pdata, 1);
778 		break;
779 	case PREISP_POWER_OFF:
780 		ret = rk1608_set_power(pdata, 0);
781 		break;
782 	case PREISP_DOWNLOAD_FW: {
783 		char fw_name[PREISP_FW_NAME_LEN];
784 
785 		if (strncpy_from_user(fw_name, ubuf, PREISP_FW_NAME_LEN) <= 0) {
786 			ret = -EFAULT;
787 			break;
788 		}
789 		dev_info(pdata->dev, "download fw:%s\n", fw_name);
790 		ret = rk1608_download_fw(pdata, pdata->spi, fw_name);
791 		break;
792 	}
793 	case PREISP_WRITE: {
794 		struct preisp_apb_pkt pkt;
795 		s32 *data;
796 
797 		if (copy_from_user(&pkt, ubuf, sizeof(pkt))) {
798 			ret = -EFAULT;
799 			break;
800 		}
801 		pkt.data_len = MIN(pkt.data_len, RK1608_MAX_OP_BYTES);
802 		data = memdup_user((void __user *)pkt.data, pkt.data_len);
803 		if (IS_ERR(data)) {
804 			ret = (long)ERR_PTR((long)data);
805 			break;
806 		}
807 
808 		ret = rk1608_safe_write(pdata, pdata->spi, pkt.addr, data, pkt.data_len);
809 		kfree(data);
810 		break;
811 	}
812 	case PREISP_READ: {
813 		struct preisp_apb_pkt pkt;
814 		s32 *data;
815 
816 		if (copy_from_user(&pkt, ubuf, sizeof(pkt))) {
817 			ret = -EFAULT;
818 			break;
819 		}
820 		pkt.data_len = MIN(pkt.data_len, RK1608_MAX_OP_BYTES);
821 		data = kmalloc(pkt.data_len, GFP_KERNEL);
822 		if (!data) {
823 			ret = -ENOMEM;
824 			break;
825 		}
826 
827 		ret = rk1608_safe_read(pdata, pdata->spi, pkt.addr, data, pkt.data_len);
828 		if (ret) {
829 			kfree(data);
830 			break;
831 		}
832 		ret = copy_to_user((void __user *)pkt.data, data, pkt.data_len);
833 
834 		kfree(data);
835 		break;
836 	}
837 	case PREISP_ST_QUERY: {
838 		s32 state;
839 
840 		ret = rk1608_state_query(pdata->spi, &state);
841 		if (ret)
842 			break;
843 
844 		ret = put_user(state, (s32 __user *)ubuf);
845 		break;
846 	}
847 	case PREISP_IRQ_REQUEST: {
848 		int int_num = arg;
849 
850 		ret = rk1608_interrupt_request(pdata->spi, int_num);
851 		break;
852 	}
853 	case PREISP_SEND_MSG: {
854 		struct msg *msg;
855 		u32 len;
856 
857 		if (get_user(len, (u32 __user *)ubuf)) {
858 			ret = -EFAULT;
859 			break;
860 		}
861 		len = len * sizeof(s32);
862 		msg = memdup_user(ubuf, len);
863 		if (IS_ERR(msg)) {
864 			ret = (long)ERR_PTR((long)msg);
865 			break;
866 		}
867 
868 #if DEBUG_DUMP_ALL_SEND_RECV_MSG == 1
869 		int32_hexdump("send msg:", (s32 *)msg, len);
870 #endif
871 
872 		ret = rk1608_send_msg_to_dsp(pdata, msg);
873 		kfree(msg);
874 		break;
875 	}
876 	case PREISP_QUERY_MSG: {
877 		struct msg *msg;
878 
879 		ret = msq_recv_msg(&client->q, &msg);
880 		if (ret)
881 			break;
882 
883 		ret = put_user(msg->size, (u32 __user *)ubuf);
884 		break;
885 	}
886 	case PREISP_RECV_MSG: {
887 		struct msg *msg;
888 
889 		ret = msq_recv_msg(&client->q, &msg);
890 		if (ret)
891 			break;
892 
893 		ret = copy_to_user(ubuf, msg, msg->size * sizeof(u32));
894 		msq_free_received_msg(&client->q, msg);
895 		break;
896 	}
897 	case PREISP_CLIENT_CONNECT: {
898 		client->id = (int)arg;
899 		ret = rk1608_client_connect(pdata, client);
900 		break;
901 	}
902 	case PREISP_CLIENT_DISCONNECT: {
903 		rk1608_client_disconnect(pdata, client);
904 		client->id = INVALID_ID;
905 		break;
906 	}
907 	default:
908 		ret = -EFAULT;
909 		break;
910 	}
911 
912 	return ret;
913 }
914 
915 #ifdef CONFIG_COMPAT
916 #define PREISP_WRITE32		_IOW('p', 6, struct preisp_apb_pkt32)
917 #define PREISP_READ32		_IOR('p', 7, struct preisp_apb_pkt32)
918 
919 struct preisp_apb_pkt32 {
920 	s32 data_len;
921 	s32 addr;
922 	compat_uptr_t data;
923 };
924 
rk1608_compat_ioctl(struct file * file,unsigned int cmd,unsigned long arg)925 static long rk1608_compat_ioctl(struct file *file, unsigned int cmd,
926 				unsigned long arg)
927 {
928 	int ret = 0;
929 	struct preisp_apb_pkt32 pkt32;
930 	struct preisp_apb_pkt *pkt;
931 
932 	switch (cmd) {
933 	case PREISP_WRITE32:
934 		cmd = PREISP_WRITE;
935 		break;
936 	case PREISP_READ32:
937 		cmd = PREISP_READ;
938 		break;
939 	default:
940 		break;
941 	}
942 
943 	switch (cmd) {
944 	case PREISP_WRITE:
945 	case PREISP_READ:
946 		if (copy_from_user(&pkt32, (void __user *)arg, sizeof(pkt32)))
947 			return -EFAULT;
948 
949 		pkt = compat_alloc_user_space(sizeof(*pkt));
950 		if (!pkt ||
951 		    put_user(pkt32.data_len, &pkt->data_len) ||
952 		    put_user(pkt32.addr, &pkt->addr) ||
953 		    put_user(compat_ptr(pkt32.data), &pkt->data))
954 			return -EFAULT;
955 
956 		ret = rk1608_dev_ioctl(file, cmd, (unsigned long)pkt);
957 		break;
958 	default:
959 		ret = rk1608_dev_ioctl(file, cmd, arg);
960 		break;
961 	}
962 
963 	return ret;
964 }
965 #endif
966 
rk1608_dev_poll(struct file * file,poll_table * wait)967 static unsigned int rk1608_dev_poll(struct file *file, poll_table *wait)
968 {
969 	struct rk1608_client *client = file->private_data;
970 	unsigned int mask = 0;
971 
972 	poll_wait(file, &client->wait, wait);
973 
974 	if (!msq_is_empty(&client->q))
975 		mask |= POLLIN;
976 
977 	return mask;
978 }
979 
980 static const struct file_operations rk1608_fops = {
981 	.owner = THIS_MODULE,
982 	.open = rk1608_dev_open,
983 	.release = rk1608_dev_release,
984 	.write = rk1608_dev_write,
985 	.poll = rk1608_dev_poll,
986 	.unlocked_ioctl = rk1608_dev_ioctl,
987 #ifdef CONFIG_COMPAT
988 	.compat_ioctl = rk1608_compat_ioctl,
989 #endif
990 };
991 
rk1608_dev_receive_msg(struct rk1608_state * pdata,struct msg * msg)992 void rk1608_dev_receive_msg(struct rk1608_state *pdata, struct msg *msg)
993 {
994 	struct rk1608_client_list *s = &pdata->clients;
995 	struct rk1608_client *client;
996 
997 #if DEBUG_DUMP_ALL_SEND_RECV_MSG == 1
998 	int32_hexdump("recv msg:", (s32 *)msg, msg->size * 4);
999 #endif
1000 
1001 	mutex_lock(&s->mutex);
1002 	list_for_each_entry(client, &s->list, list) {
1003 		if (client->id == msg->id.camera_id) {
1004 			msq_send_msg(&client->q, msg);
1005 			wake_up_interruptible(&client->wait);
1006 		}
1007 	}
1008 	mutex_unlock(&s->mutex);
1009 }
1010 
rk1608_dev_register(struct rk1608_state * pdata)1011 int rk1608_dev_register(struct rk1608_state *pdata)
1012 {
1013 	int ret;
1014 
1015 	rk1608_client_list_init(&pdata->clients);
1016 
1017 	pdata->misc.minor = MISC_DYNAMIC_MINOR;
1018 	pdata->misc.name = "rk_preisp";
1019 	pdata->misc.fops = &rk1608_fops;
1020 
1021 	ret = misc_register(&pdata->misc);
1022 	if (ret < 0)
1023 		dev_err(pdata->dev, "Error: misc_register returned %d\n", ret);
1024 
1025 	return 0;
1026 }
1027 
rk1608_dev_unregister(struct rk1608_state * pdata)1028 void rk1608_dev_unregister(struct rk1608_state *pdata)
1029 {
1030 	misc_deregister(&pdata->misc);
1031 }
1032