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