blob: e408c7d70f5b396cc8aba34aa7a444435f93cdab [file] [log] [blame]
Meng Wang688a8672019-01-29 13:43:33 +08001// SPDX-License-Identifier: GPL-2.0-only
Meng Wang61af6842018-09-10 17:47:55 +08002/*
3 * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304 */
5
6#include <linux/compat.h>
7#include <linux/fs.h>
8#include <linux/module.h>
9#include <linux/miscdevice.h>
10#include <linux/sched.h>
11#include <linux/slab.h>
12#include <linux/wait.h>
13#include <linux/input.h>
14#include <linux/uaccess.h>
15#include <linux/time.h>
16#include <linux/kmemleak.h>
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053017#include <linux/mutex.h>
Laxminath Kasam605b42f2017-08-01 22:02:15 +053018#include <dsp/apr_audio-v2.h>
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053019#include "q6usm.h"
Laxminath Kasam605b42f2017-08-01 22:02:15 +053020#include "usf.h"
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053021#include "usfcdev.h"
Laxminath Kasam8b1366a2017-10-05 01:44:16 +053022#include "q6_init.h"
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053023
24/* The driver version*/
25#define DRV_VERSION "1.7.1"
26#define USF_VERSION_ID 0x0171
27
28/* Standard timeout in the asynchronous ops */
29#define USF_TIMEOUT_JIFFIES (1*HZ) /* 1 sec */
30
31/* Undefined USF device */
32#define USF_UNDEF_DEV_ID 0xffff
33
34/* TX memory mapping flag */
35#define USF_VM_READ 1
36/* RX memory mapping flag */
37#define USF_VM_WRITE 2
38
39/* Number of events, copied from the user space to kernel one */
40#define USF_EVENTS_PORTION_SIZE 20
41
42/* Indexes in range definitions */
43#define MIN_IND 0
44#define MAX_IND 1
45
46/* The coordinates indexes */
47#define X_IND 0
48#define Y_IND 1
49#define Z_IND 2
50
51/* Shared memory limits */
52/* max_buf_size = (port_size(65535*2) * port_num(8) * group_size(3) */
53#define USF_MAX_BUF_SIZE 3145680
54#define USF_MAX_BUF_NUM 32
55
56/* max size for buffer set from user space */
57#define USF_MAX_USER_BUF_SIZE 100000
58
59/* Place for opreation result, received from QDSP6 */
60#define APR_RESULT_IND 1
61
62/* Place for US detection result, received from QDSP6 */
63#define APR_US_DETECT_RESULT_IND 0
64
65#define BITS_IN_BYTE 8
66
67/* Time to stay awake after tx read event (e.g., proximity) */
68#define STAY_AWAKE_AFTER_READ_MSECS 3000
69
70/* The driver states */
71enum usf_state_type {
72 USF_IDLE_STATE,
73 USF_OPENED_STATE,
74 USF_CONFIGURED_STATE,
75 USF_WORK_STATE,
76 USF_ADSP_RESTART_STATE,
77 USF_ERROR_STATE
78};
79
80/* The US detection status upon FW/HW based US detection results */
81enum usf_us_detect_type {
82 USF_US_DETECT_UNDEF,
83 USF_US_DETECT_YES,
84 USF_US_DETECT_NO
85};
86
87struct usf_xx_type {
88 /* Name of the client - event calculator */
89 char client_name[USF_MAX_CLIENT_NAME_SIZE];
90 /* The driver state in TX or RX direction */
91 enum usf_state_type usf_state;
92 /* wait for q6 events mechanism */
93 wait_queue_head_t wait;
94 /* IF with q6usm info */
95 struct us_client *usc;
96 /* Q6:USM' Encoder/decoder configuration */
97 struct us_encdec_cfg encdec_cfg;
98 /* Shared buffer (with Q6:USM) size */
99 uint32_t buffer_size;
100 /* Number of the shared buffers (with Q6:USM) */
101 uint32_t buffer_count;
102 /* Shared memory (Cyclic buffer with 1 gap) control */
103 uint32_t new_region;
104 uint32_t prev_region;
105 /* Q6:USM's events handler */
106 void (*cb)(uint32_t, uint32_t, uint32_t *, void *);
107 /* US detection result */
108 enum usf_us_detect_type us_detect_type;
109 /* User's update info isn't acceptable */
110 u8 user_upd_info_na;
111};
112
113struct usf_type {
114 /* TX device component configuration & control */
115 struct usf_xx_type usf_tx;
116 /* RX device component configuration & control */
117 struct usf_xx_type usf_rx;
118 /* Index into the opened device container */
119 /* To prevent mutual usage of the same device */
120 uint16_t dev_ind;
121 /* Event types, supported by device */
122 uint16_t event_types;
123 /* The input devices are "input" module registered clients */
124 struct input_dev *input_ifs[USF_MAX_EVENT_IND];
125 /* Bitmap of types of events, conflicting to USF's ones */
126 uint16_t conflicting_event_types;
127 /* Bitmap of types of events from devs, conflicting with USF */
128 uint16_t conflicting_event_filters;
129 /* The requested buttons bitmap */
130 uint16_t req_buttons_bitmap;
131 /* Mutex for exclusive operations (all public APIs) */
132 struct mutex mutex;
133};
134
135struct usf_input_dev_type {
136 /* Input event type, supported by the input device */
137 uint16_t event_type;
138 /* Input device name */
139 const char *input_dev_name;
140 /* Input device registration function */
141 int (*prepare_dev)(uint16_t, struct usf_type *,
142 struct us_input_info_type *,
143 const char *);
144 /* Input event notification function */
145 void (*notify_event)(struct usf_type *,
146 uint16_t,
147 struct usf_event_type *
148 );
149};
150
151
152/* The MAX number of the supported devices */
153#define MAX_DEVS_NUMBER 1
154
155/*
156 * code for a special button that is used to show/hide a
157 * hovering cursor in the input framework. Must be in
158 * sync with the button code definition in the framework
159 * (EventHub.h)
160 */
161#define BTN_USF_HOVERING_CURSOR 0x230
162
163/* Supported buttons container */
164static const int s_button_map[] = {
165 BTN_STYLUS,
166 BTN_STYLUS2,
167 BTN_TOOL_PEN,
168 BTN_TOOL_RUBBER,
169 BTN_TOOL_FINGER,
170 BTN_USF_HOVERING_CURSOR
171};
172
173/* The opened devices container */
174static atomic_t s_opened_devs[MAX_DEVS_NUMBER];
175
176static struct wakeup_source usf_wakeup_source;
177
178#define USF_NAME_PREFIX "usf_"
179#define USF_NAME_PREFIX_SIZE 4
180
181
182static struct input_dev *allocate_dev(uint16_t ind, const char *name)
183{
184 struct input_dev *in_dev = input_allocate_device();
185
186 if (in_dev == NULL) {
187 pr_err("%s: input_allocate_device() failed\n", __func__);
188 } else {
189 /* Common part configuration */
190 in_dev->name = name;
191 in_dev->phys = NULL;
192 in_dev->id.bustype = BUS_HOST;
193 in_dev->id.vendor = 0x0001;
194 in_dev->id.product = 0x0001;
195 in_dev->id.version = USF_VERSION_ID;
196 }
197 return in_dev;
198}
199
200static int prepare_tsc_input_device(uint16_t ind,
201 struct usf_type *usf_info,
202 struct us_input_info_type *input_info,
203 const char *name)
204{
205 int i = 0;
206
207 int num_buttons = min(ARRAY_SIZE(s_button_map),
208 sizeof(input_info->req_buttons_bitmap) *
209 BITS_IN_BYTE);
210 uint16_t max_buttons_bitmap = ((1 << ARRAY_SIZE(s_button_map)) - 1);
211
212 struct input_dev *in_dev = allocate_dev(ind, name);
213
214 if (in_dev == NULL)
215 return -ENOMEM;
216
217 if (input_info->req_buttons_bitmap > max_buttons_bitmap) {
218 pr_err("%s: Requested buttons[%d] exceeds max buttons available[%d]\n",
219 __func__,
220 input_info->req_buttons_bitmap,
221 max_buttons_bitmap);
222 input_free_device(in_dev);
223 return -EINVAL;
224 }
225
226 usf_info->input_ifs[ind] = in_dev;
227 usf_info->req_buttons_bitmap =
228 input_info->req_buttons_bitmap;
229 in_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
230 in_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
231
232 for (i = 0; i < num_buttons; i++)
233 if (input_info->req_buttons_bitmap & (1 << i))
234 in_dev->keybit[BIT_WORD(s_button_map[i])] |=
235 BIT_MASK(s_button_map[i]);
236
237 input_set_abs_params(in_dev, ABS_X,
238 input_info->tsc_x_dim[MIN_IND],
239 input_info->tsc_x_dim[MAX_IND],
240 0, 0);
241 input_set_abs_params(in_dev, ABS_Y,
242 input_info->tsc_y_dim[MIN_IND],
243 input_info->tsc_y_dim[MAX_IND],
244 0, 0);
245 input_set_abs_params(in_dev, ABS_DISTANCE,
246 input_info->tsc_z_dim[MIN_IND],
247 input_info->tsc_z_dim[MAX_IND],
248 0, 0);
249
250 input_set_abs_params(in_dev, ABS_PRESSURE,
251 input_info->tsc_pressure[MIN_IND],
252 input_info->tsc_pressure[MAX_IND],
253 0, 0);
254
255 input_set_abs_params(in_dev, ABS_TILT_X,
256 input_info->tsc_x_tilt[MIN_IND],
257 input_info->tsc_x_tilt[MAX_IND],
258 0, 0);
259 input_set_abs_params(in_dev, ABS_TILT_Y,
260 input_info->tsc_y_tilt[MIN_IND],
261 input_info->tsc_y_tilt[MAX_IND],
262 0, 0);
263
264 return 0;
265}
266
267static int prepare_mouse_input_device(uint16_t ind, struct usf_type *usf_info,
268 struct us_input_info_type *input_info,
269 const char *name)
270{
271 struct input_dev *in_dev = allocate_dev(ind, name);
272
273 if (in_dev == NULL)
274 return -ENOMEM;
275
276 usf_info->input_ifs[ind] = in_dev;
277 in_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
278
279 in_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
280 BIT_MASK(BTN_RIGHT) |
281 BIT_MASK(BTN_MIDDLE);
282 in_dev->relbit[0] = BIT_MASK(REL_X) |
283 BIT_MASK(REL_Y) |
284 BIT_MASK(REL_Z);
285
286 return 0;
287}
288
289static int prepare_keyboard_input_device(
290 uint16_t ind,
291 struct usf_type *usf_info,
292 struct us_input_info_type *input_info,
293 const char *name)
294{
295 struct input_dev *in_dev = allocate_dev(ind, name);
296
297 if (in_dev == NULL)
298 return -ENOMEM;
299
300 usf_info->input_ifs[ind] = in_dev;
301 in_dev->evbit[0] |= BIT_MASK(EV_KEY);
302 /* All keys are permitted */
303 memset(in_dev->keybit, 0xff, sizeof(in_dev->keybit));
304
305 return 0;
306}
307
308static void notify_tsc_event(struct usf_type *usf_info,
309 uint16_t if_ind,
310 struct usf_event_type *event)
311
312{
313 int i = 0;
314 int num_buttons = min(ARRAY_SIZE(s_button_map),
315 sizeof(usf_info->req_buttons_bitmap) *
316 BITS_IN_BYTE);
317
318 struct input_dev *input_if = usf_info->input_ifs[if_ind];
319 struct point_event_type *pe = &(event->event_data.point_event);
320
321 input_report_abs(input_if, ABS_X, pe->coordinates[X_IND]);
322 input_report_abs(input_if, ABS_Y, pe->coordinates[Y_IND]);
323 input_report_abs(input_if, ABS_DISTANCE, pe->coordinates[Z_IND]);
324
325 input_report_abs(input_if, ABS_TILT_X, pe->inclinations[X_IND]);
326 input_report_abs(input_if, ABS_TILT_Y, pe->inclinations[Y_IND]);
327
328 input_report_abs(input_if, ABS_PRESSURE, pe->pressure);
329 input_report_key(input_if, BTN_TOUCH, !!(pe->pressure));
330
331 for (i = 0; i < num_buttons; i++) {
332 uint16_t mask = (1 << i),
333 btn_state = !!(pe->buttons_state_bitmap & mask);
334 if (usf_info->req_buttons_bitmap & mask)
335 input_report_key(input_if, s_button_map[i], btn_state);
336 }
337
338 input_sync(input_if);
339
340 pr_debug("%s: TSC event: xyz[%d;%d;%d], incl[%d;%d], pressure[%d], buttons[%d]\n",
341 __func__,
342 pe->coordinates[X_IND],
343 pe->coordinates[Y_IND],
344 pe->coordinates[Z_IND],
345 pe->inclinations[X_IND],
346 pe->inclinations[Y_IND],
347 pe->pressure,
348 pe->buttons_state_bitmap);
349}
350
351static void notify_mouse_event(struct usf_type *usf_info,
352 uint16_t if_ind,
353 struct usf_event_type *event)
354{
355 struct input_dev *input_if = usf_info->input_ifs[if_ind];
356 struct mouse_event_type *me = &(event->event_data.mouse_event);
357
358 input_report_rel(input_if, REL_X, me->rels[X_IND]);
359 input_report_rel(input_if, REL_Y, me->rels[Y_IND]);
360 input_report_rel(input_if, REL_Z, me->rels[Z_IND]);
361
362 input_report_key(input_if, BTN_LEFT,
363 me->buttons_states & USF_BUTTON_LEFT_MASK);
364 input_report_key(input_if, BTN_MIDDLE,
365 me->buttons_states & USF_BUTTON_MIDDLE_MASK);
366 input_report_key(input_if, BTN_RIGHT,
367 me->buttons_states & USF_BUTTON_RIGHT_MASK);
368
369 input_sync(input_if);
370
371 pr_debug("%s: mouse event: dx[%d], dy[%d], buttons_states[%d]\n",
372 __func__, me->rels[X_IND],
373 me->rels[Y_IND], me->buttons_states);
374}
375
376static void notify_key_event(struct usf_type *usf_info,
377 uint16_t if_ind,
378 struct usf_event_type *event)
379{
380 struct input_dev *input_if = usf_info->input_ifs[if_ind];
381 struct key_event_type *ke = &(event->event_data.key_event);
382
383 input_report_key(input_if, ke->key, ke->key_state);
384 input_sync(input_if);
385 pr_debug("%s: key event: key[%d], state[%d]\n",
386 __func__,
387 ke->key,
388 ke->key_state);
389
390}
391
392static struct usf_input_dev_type s_usf_input_devs[] = {
393 {USF_TSC_EVENT, "usf_tsc",
394 prepare_tsc_input_device, notify_tsc_event},
395 {USF_TSC_PTR_EVENT, "usf_tsc_ptr",
396 prepare_tsc_input_device, notify_tsc_event},
397 {USF_MOUSE_EVENT, "usf_mouse",
398 prepare_mouse_input_device, notify_mouse_event},
399 {USF_KEYBOARD_EVENT, "usf_kb",
400 prepare_keyboard_input_device, notify_key_event},
401 {USF_TSC_EXT_EVENT, "usf_tsc_ext",
402 prepare_tsc_input_device, notify_tsc_event},
403};
404
405static void usf_rx_cb(uint32_t opcode, uint32_t token,
406 uint32_t *payload, void *priv)
407{
408 struct usf_xx_type *usf_xx = (struct usf_xx_type *) priv;
409
410 if (usf_xx == NULL) {
411 pr_err("%s: the private data is NULL\n", __func__);
412 return;
413 }
414
415 switch (opcode) {
416 case Q6USM_EVENT_WRITE_DONE:
417 wake_up(&usf_xx->wait);
418 break;
419
420 case RESET_EVENTS:
421 pr_err("%s: received RESET_EVENTS\n", __func__);
422 usf_xx->usf_state = USF_ADSP_RESTART_STATE;
423 wake_up(&usf_xx->wait);
424 break;
425
426 default:
427 break;
428 }
429}
430
431static void usf_tx_cb(uint32_t opcode, uint32_t token,
432 uint32_t *payload, void *priv)
433{
434 struct usf_xx_type *usf_xx = (struct usf_xx_type *) priv;
435
436 if (usf_xx == NULL) {
437 pr_err("%s: the private data is NULL\n", __func__);
438 return;
439 }
440
441 switch (opcode) {
442 case Q6USM_EVENT_READ_DONE:
443 pr_debug("%s: acquiring %d msec wake lock\n", __func__,
444 STAY_AWAKE_AFTER_READ_MSECS);
445 __pm_wakeup_event(&usf_wakeup_source,
446 STAY_AWAKE_AFTER_READ_MSECS);
447 if (token == USM_WRONG_TOKEN)
448 usf_xx->usf_state = USF_ERROR_STATE;
449 usf_xx->new_region = token;
450 wake_up(&usf_xx->wait);
451 break;
452
453 case Q6USM_EVENT_SIGNAL_DETECT_RESULT:
454 usf_xx->us_detect_type = (payload[APR_US_DETECT_RESULT_IND]) ?
455 USF_US_DETECT_YES :
456 USF_US_DETECT_NO;
457
458 wake_up(&usf_xx->wait);
459 break;
460
461 case APR_BASIC_RSP_RESULT:
462 if (payload[APR_RESULT_IND]) {
463 usf_xx->usf_state = USF_ERROR_STATE;
464 usf_xx->new_region = USM_WRONG_TOKEN;
465 wake_up(&usf_xx->wait);
466 }
467 break;
468
469 case RESET_EVENTS:
470 pr_err("%s: received RESET_EVENTS\n", __func__);
471 usf_xx->usf_state = USF_ADSP_RESTART_STATE;
472 wake_up(&usf_xx->wait);
473 break;
474
475 default:
476 break;
477 }
478}
479
480static void release_xx(struct usf_xx_type *usf_xx)
481{
482 if (usf_xx != NULL) {
483 if (usf_xx->usc) {
484 q6usm_us_client_free(usf_xx->usc);
485 usf_xx->usc = NULL;
486 }
487
488 if (usf_xx->encdec_cfg.params != NULL) {
489 kfree(usf_xx->encdec_cfg.params);
490 usf_xx->encdec_cfg.params = NULL;
491 }
492 }
493}
494
495static void usf_disable(struct usf_xx_type *usf_xx)
496{
497 if (usf_xx != NULL) {
498 if ((usf_xx->usf_state != USF_IDLE_STATE) &&
499 (usf_xx->usf_state != USF_OPENED_STATE)) {
500 (void)q6usm_cmd(usf_xx->usc, CMD_CLOSE);
501 usf_xx->usf_state = USF_OPENED_STATE;
502 wake_up(&usf_xx->wait);
503 }
504 release_xx(usf_xx);
505 }
506}
507
508static int config_xx(struct usf_xx_type *usf_xx, struct us_xx_info_type *config)
509{
510 int rc = 0;
511 uint16_t data_map_size = 0;
512 uint16_t min_map_size = 0;
513
514 if ((usf_xx == NULL) ||
515 (config == NULL))
516 return -EINVAL;
517
518 if ((config->buf_size == 0) ||
519 (config->buf_size > USF_MAX_BUF_SIZE) ||
520 (config->buf_num == 0) ||
521 (config->buf_num > USF_MAX_BUF_NUM)) {
522 pr_err("%s: wrong params: buf_size=%d; buf_num=%d\n",
523 __func__, config->buf_size, config->buf_num);
524 return -EINVAL;
525 }
526
527 data_map_size = sizeof(usf_xx->encdec_cfg.cfg_common.data_map);
528 min_map_size = min(data_map_size, config->port_cnt);
529
530 if (config->client_name != NULL) {
531 if (strncpy_from_user(usf_xx->client_name,
532 (char __user *)config->client_name,
533 sizeof(usf_xx->client_name) - 1) < 0) {
534 pr_err("%s: get client name failed\n", __func__);
535 return -EINVAL;
536 }
537 }
538
539 pr_debug("%s: name=%s; buf_size:%d; dev_id:0x%x; sample_rate:%d\n",
540 __func__, usf_xx->client_name, config->buf_size,
541 config->dev_id, config->sample_rate);
542
543 pr_debug("%s: buf_num:%d; format:%d; port_cnt:%d; data_size=%d\n",
544 __func__, config->buf_num, config->stream_format,
545 config->port_cnt, config->params_data_size);
546
547 pr_debug("%s: id[0]=%d, id[1]=%d, id[2]=%d, id[3]=%d, id[4]=%d,\n",
548 __func__,
549 config->port_id[0],
550 config->port_id[1],
551 config->port_id[2],
552 config->port_id[3],
553 config->port_id[4]);
554
555 pr_debug("id[5]=%d, id[6]=%d, id[7]=%d\n",
556 config->port_id[5],
557 config->port_id[6],
558 config->port_id[7]);
559
560 /* q6usm allocation & configuration */
561 usf_xx->buffer_size = config->buf_size;
562 usf_xx->buffer_count = config->buf_num;
563 usf_xx->encdec_cfg.cfg_common.bits_per_sample =
564 config->bits_per_sample;
565 usf_xx->encdec_cfg.cfg_common.sample_rate = config->sample_rate;
566 /* AFE port e.g. AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_RX */
567 usf_xx->encdec_cfg.cfg_common.dev_id = config->dev_id;
568
569 usf_xx->encdec_cfg.cfg_common.ch_cfg = config->port_cnt;
570 memcpy((void *)&usf_xx->encdec_cfg.cfg_common.data_map,
571 (void *)config->port_id,
572 min_map_size);
573
574 usf_xx->encdec_cfg.format_id = config->stream_format;
575 usf_xx->encdec_cfg.params_size = config->params_data_size;
576 usf_xx->user_upd_info_na = 1; /* it's used in US_GET_TX_UPDATE */
577
578 if (config->params_data_size > 0) { /* transparent data copy */
579 usf_xx->encdec_cfg.params = kzalloc(config->params_data_size,
580 GFP_KERNEL);
581 /* False memory leak here - pointer in packed struct
582 * is undetected by kmemleak tool
583 */
584 kmemleak_ignore(usf_xx->encdec_cfg.params);
585 if (usf_xx->encdec_cfg.params == NULL) {
586 pr_err("%s: params memory alloc[%d] failure\n",
587 __func__,
588 config->params_data_size);
589 return -ENOMEM;
590 }
591 rc = copy_from_user(usf_xx->encdec_cfg.params,
592 (uint8_t __user *)config->params_data,
593 config->params_data_size);
594 if (rc) {
595 pr_err("%s: transparent data copy failure\n",
596 __func__);
597 kfree(usf_xx->encdec_cfg.params);
598 usf_xx->encdec_cfg.params = NULL;
599 return -EFAULT;
600 }
601 pr_debug("%s: params_size[%d]; params[%d,%d,%d,%d, %d]\n",
602 __func__,
603 config->params_data_size,
604 usf_xx->encdec_cfg.params[0],
605 usf_xx->encdec_cfg.params[1],
606 usf_xx->encdec_cfg.params[2],
607 usf_xx->encdec_cfg.params[3],
608 usf_xx->encdec_cfg.params[4]
609 );
610 }
611
612 usf_xx->usc = q6usm_us_client_alloc(usf_xx->cb, (void *)usf_xx);
613 if (!usf_xx->usc) {
614 pr_err("%s: Could not allocate q6usm client\n", __func__);
615 rc = -EFAULT;
616 }
617
618 return rc;
619}
620
621static bool usf_match(uint16_t event_type_ind, struct input_dev *dev)
622{
623 bool rc = false;
624
625 rc = (event_type_ind < MAX_EVENT_TYPE_NUM) &&
626 ((dev->name == NULL) ||
627 strcmp(dev->name, USF_NAME_PREFIX));
628 pr_debug("%s: name=[%s]; rc=%d\n",
629 __func__, dev->name, rc);
630
631 return rc;
632}
633
634static bool usf_register_conflicting_events(uint16_t event_types)
635{
636 bool rc = true;
637 uint16_t ind = 0;
638 uint16_t mask = 1;
639
640 for (ind = 0; ind < MAX_EVENT_TYPE_NUM; ++ind) {
641 if (event_types & mask) {
642 rc = usfcdev_register(ind, usf_match);
643 if (!rc)
644 break;
645 }
646 mask = mask << 1;
647 }
648
649 return rc;
650}
651
652static void usf_unregister_conflicting_events(uint16_t event_types)
653{
654 uint16_t ind = 0;
655 uint16_t mask = 1;
656
657 for (ind = 0; ind < MAX_EVENT_TYPE_NUM; ++ind) {
658 if (event_types & mask)
659 usfcdev_unregister(ind);
660 mask = mask << 1;
661 }
662}
663
664static void usf_set_event_filters(struct usf_type *usf, uint16_t event_filters)
665{
666 uint16_t ind = 0;
667 uint16_t mask = 1;
668
669 if (usf->conflicting_event_filters != event_filters) {
670 for (ind = 0; ind < MAX_EVENT_TYPE_NUM; ++ind) {
671 if (usf->conflicting_event_types & mask)
672 usfcdev_set_filter(ind, event_filters&mask);
673 mask = mask << 1;
674 }
675 usf->conflicting_event_filters = event_filters;
676 }
677}
678
679static int register_input_device(struct usf_type *usf_info,
680 struct us_input_info_type *input_info)
681{
682 int rc = 0;
683 bool ret = true;
684 uint16_t ind = 0;
685
686 if ((usf_info == NULL) ||
687 (input_info == NULL) ||
688 !(input_info->event_types & USF_ALL_EVENTS)) {
689 pr_err("%s: wrong input parameter(s)\n", __func__);
690 return -EINVAL;
691 }
692
693 for (ind = 0; ind < USF_MAX_EVENT_IND; ++ind) {
694 if (usf_info->input_ifs[ind] != NULL) {
695 pr_err("%s: input_if[%d] is already allocated\n",
696 __func__, ind);
697 return -EFAULT;
698 }
699 if ((input_info->event_types &
700 s_usf_input_devs[ind].event_type) &&
701 s_usf_input_devs[ind].prepare_dev) {
702 rc = (*s_usf_input_devs[ind].prepare_dev)(
703 ind,
704 usf_info,
705 input_info,
706 s_usf_input_devs[ind].input_dev_name);
707 if (rc)
708 return rc;
709
710 rc = input_register_device(usf_info->input_ifs[ind]);
711 if (rc) {
712 pr_err("%s: input_reg_dev() failed; rc=%d\n",
713 __func__, rc);
714 input_free_device(usf_info->input_ifs[ind]);
715 usf_info->input_ifs[ind] = NULL;
716 } else {
717 usf_info->event_types |=
718 s_usf_input_devs[ind].event_type;
719 pr_debug("%s: input device[%s] was registered\n",
720 __func__,
721 s_usf_input_devs[ind].input_dev_name);
722 }
723 } /* supported event */
724 } /* event types loop */
725
726 ret = usf_register_conflicting_events(
727 input_info->conflicting_event_types);
728 if (ret)
729 usf_info->conflicting_event_types =
730 input_info->conflicting_event_types;
731
732 return 0;
733}
734
735
736static void handle_input_event(struct usf_type *usf_info,
737 uint16_t event_counter,
738 struct usf_event_type __user *event)
739{
740 uint16_t ind = 0;
741 uint16_t events_num = 0;
742 struct usf_event_type usf_events[USF_EVENTS_PORTION_SIZE];
743 int rc = 0;
744
745 if ((usf_info == NULL) ||
746 (event == NULL) || (!event_counter)) {
747 return;
748 }
749
750 while (event_counter > 0) {
751 if (event_counter > USF_EVENTS_PORTION_SIZE) {
752 events_num = USF_EVENTS_PORTION_SIZE;
753 event_counter -= USF_EVENTS_PORTION_SIZE;
754 } else {
755 events_num = event_counter;
756 event_counter = 0;
757 }
758 rc = copy_from_user(usf_events,
759 (struct usf_event_type __user *)event,
760 events_num * sizeof(struct usf_event_type));
761 if (rc) {
762 pr_err("%s: copy upd_rx_info from user; rc=%d\n",
763 __func__, rc);
764 return;
765 }
766 for (ind = 0; ind < events_num; ++ind) {
767 struct usf_event_type *p_event = &usf_events[ind];
768 uint16_t if_ind = p_event->event_type_ind;
769
770 if ((if_ind >= USF_MAX_EVENT_IND) ||
771 (usf_info->input_ifs[if_ind] == NULL))
772 continue; /* event isn't supported */
773
774 if (s_usf_input_devs[if_ind].notify_event)
775 (*s_usf_input_devs[if_ind].notify_event)(
776 usf_info,
777 if_ind,
778 p_event);
779 } /* loop in the portion */
780 } /* all events loop */
781}
782
783static int usf_start_tx(struct usf_xx_type *usf_xx)
784{
785 int rc = q6usm_run(usf_xx->usc, 0, 0, 0);
786
787 pr_debug("%s: tx: q6usm_run; rc=%d\n", __func__, rc);
788 if (!rc) {
789 if (usf_xx->buffer_count >= USM_MIN_BUF_CNT) {
790 /* supply all buffers */
791 rc = q6usm_read(usf_xx->usc,
792 usf_xx->buffer_count);
793 pr_debug("%s: q6usm_read[%d]\n",
794 __func__, rc);
795
796 if (rc)
797 pr_err("%s: buf read failed",
798 __func__);
799 else
800 usf_xx->usf_state =
801 USF_WORK_STATE;
802 } else
803 usf_xx->usf_state =
804 USF_WORK_STATE;
805 }
806
807 return rc;
808} /* usf_start_tx */
809
810static int usf_start_rx(struct usf_xx_type *usf_xx)
811{
812 int rc = q6usm_run(usf_xx->usc, 0, 0, 0);
813
814 pr_debug("%s: rx: q6usm_run; rc=%d\n",
815 __func__, rc);
816 if (!rc)
817 usf_xx->usf_state = USF_WORK_STATE;
818
819 return rc;
820} /* usf_start_rx */
821
822static int __usf_set_us_detection(struct usf_type *usf,
823 struct us_detect_info_type *detect_info)
824{
825 uint32_t timeout = 0;
826 struct usm_session_cmd_detect_info *p_allocated_memory = NULL;
827 struct usm_session_cmd_detect_info usm_detect_info;
828 struct usm_session_cmd_detect_info *p_usm_detect_info =
829 &usm_detect_info;
830 uint32_t detect_info_size = sizeof(struct usm_session_cmd_detect_info);
831 struct usf_xx_type *usf_xx = &usf->usf_tx;
832 int rc = 0;
833
834 if (detect_info->us_detector != US_DETECT_FW) {
835 pr_err("%s: unsupported detector: %d\n",
836 __func__, detect_info->us_detector);
837 return -EINVAL;
838 }
839
840 if ((detect_info->params_data_size != 0) &&
841 (detect_info->params_data != NULL)) {
842 uint8_t *p_data = NULL;
843
844 detect_info_size += detect_info->params_data_size;
845 p_allocated_memory = kzalloc(detect_info_size, GFP_KERNEL);
846 if (p_allocated_memory == NULL) {
847 pr_err("%s: detect_info[%d] allocation failed\n",
848 __func__, detect_info_size);
849 return -ENOMEM;
850 }
851 p_usm_detect_info = p_allocated_memory;
852 p_data = (uint8_t *)p_usm_detect_info +
853 sizeof(struct usm_session_cmd_detect_info);
854
855 rc = copy_from_user(p_data,
856 (uint8_t __user *)(detect_info->params_data),
857 detect_info->params_data_size);
858 if (rc) {
859 pr_err("%s: copy params from user; rc=%d\n",
860 __func__, rc);
861 kfree(p_allocated_memory);
862 return -EFAULT;
863 }
864 p_usm_detect_info->algorithm_cfg_size =
865 detect_info->params_data_size;
866 } else
867 usm_detect_info.algorithm_cfg_size = 0;
868
869 p_usm_detect_info->detect_mode = detect_info->us_detect_mode;
870 p_usm_detect_info->skip_interval = detect_info->skip_time;
871
872 usf_xx->us_detect_type = USF_US_DETECT_UNDEF;
873
874 rc = q6usm_set_us_detection(usf_xx->usc,
875 p_usm_detect_info,
876 detect_info_size);
877 if (rc || (detect_info->detect_timeout == USF_NO_WAIT_TIMEOUT)) {
878 kfree(p_allocated_memory);
879 return rc;
880 }
881
882 /* Get US detection result */
883 if (detect_info->detect_timeout == USF_INFINITIVE_TIMEOUT) {
884 rc = wait_event_interruptible(usf_xx->wait,
885 (usf_xx->us_detect_type !=
886 USF_US_DETECT_UNDEF) ||
887 (usf_xx->usf_state ==
888 USF_ADSP_RESTART_STATE));
889 } else {
890 if (detect_info->detect_timeout == USF_DEFAULT_TIMEOUT)
891 timeout = USF_TIMEOUT_JIFFIES;
892 else
893 timeout = detect_info->detect_timeout * HZ;
894 }
895 rc = wait_event_interruptible_timeout(usf_xx->wait,
896 (usf_xx->us_detect_type !=
897 USF_US_DETECT_UNDEF) ||
898 (usf_xx->usf_state ==
899 USF_ADSP_RESTART_STATE), timeout);
900
901 /* In the case of aDSP restart, "no US" is assumed */
902 if (usf_xx->usf_state == USF_ADSP_RESTART_STATE)
903 rc = -EFAULT;
904
905 /* In the case of timeout, "no US" is assumed */
906 if (rc < 0)
907 pr_err("%s: Getting US detection failed rc[%d]\n",
908 __func__, rc);
909 else {
910 usf->usf_rx.us_detect_type = usf->usf_tx.us_detect_type;
911 detect_info->is_us =
912 (usf_xx->us_detect_type == USF_US_DETECT_YES);
913 }
914
915 kfree(p_allocated_memory);
916
917 return rc;
918} /* __usf_set_us_detection */
919
920static int usf_set_us_detection(struct usf_type *usf, unsigned long arg)
921{
922 struct us_detect_info_type detect_info;
923
924 int rc = copy_from_user(&detect_info,
925 (struct us_detect_info_type __user *) arg,
926 sizeof(detect_info));
927
928 if (rc) {
929 pr_err("%s: copy detect_info from user; rc=%d\n",
930 __func__, rc);
931 return -EFAULT;
932 }
933
934 if (detect_info.params_data_size > USF_MAX_USER_BUF_SIZE) {
935 pr_err("%s: user buffer size exceeds maximum\n",
936 __func__);
937 return -EFAULT;
938 }
939
940 rc = __usf_set_us_detection(usf, &detect_info);
941 if (rc < 0) {
942 pr_err("%s: set us detection failed; rc=%d\n",
943 __func__, rc);
944 return rc;
945 }
946
947 rc = copy_to_user((void __user *)arg,
948 &detect_info,
949 sizeof(detect_info));
950 if (rc) {
951 pr_err("%s: copy detect_info to user; rc=%d\n",
952 __func__, rc);
953 rc = -EFAULT;
954 }
955
956 return rc;
957} /* usf_set_us_detection */
958
959static int __usf_set_tx_info(struct usf_type *usf,
960 struct us_tx_info_type *config_tx)
961{
962 struct usf_xx_type *usf_xx = &usf->usf_tx;
963 int rc = 0;
964
965 usf_xx->new_region = USM_UNDEF_TOKEN;
966 usf_xx->prev_region = USM_UNDEF_TOKEN;
967 usf_xx->cb = usf_tx_cb;
968
969 init_waitqueue_head(&usf_xx->wait);
970
971 if (config_tx->us_xx_info.client_name != NULL) {
972 int res = strncpy_from_user(
973 usf_xx->client_name,
974 (char __user *)(config_tx->us_xx_info.client_name),
975 sizeof(usf_xx->client_name)-1);
976 if (res < 0) {
977 pr_err("%s: get client name failed\n",
978 __func__);
979 return -EINVAL;
980 }
981 }
982
983 rc = config_xx(usf_xx, &(config_tx->us_xx_info));
984 if (rc)
985 return rc;
986
987 rc = q6usm_open_read(usf_xx->usc,
988 usf_xx->encdec_cfg.format_id);
989 if (rc)
990 return rc;
991
992 rc = q6usm_us_client_buf_alloc(OUT, usf_xx->usc,
993 usf_xx->buffer_size,
994 usf_xx->buffer_count);
995 if (rc) {
996 (void)q6usm_cmd(usf_xx->usc, CMD_CLOSE);
997 return rc;
998 }
999
1000 rc = q6usm_us_param_buf_alloc(OUT, usf_xx->usc,
1001 config_tx->us_xx_info.max_get_set_param_buf_size);
1002 if (rc) {
1003 (void)q6usm_cmd(usf_xx->usc, CMD_CLOSE);
1004 return rc;
1005 }
1006
1007 rc = q6usm_enc_cfg_blk(usf_xx->usc,
1008 &usf_xx->encdec_cfg);
1009 if (!rc &&
1010 (config_tx->input_info.event_types != USF_NO_EVENT)) {
1011 rc = register_input_device(usf,
1012 &(config_tx->input_info));
1013 }
1014
1015 if (rc)
1016 (void)q6usm_cmd(usf_xx->usc, CMD_CLOSE);
1017 else
1018 usf_xx->usf_state = USF_CONFIGURED_STATE;
1019
1020 return rc;
1021} /* __usf_set_tx_info */
1022
1023static int usf_set_tx_info(struct usf_type *usf, unsigned long arg)
1024{
1025 struct us_tx_info_type config_tx;
1026
1027 int rc = copy_from_user(&config_tx,
1028 (struct us_tx_info_type __user *) arg,
1029 sizeof(config_tx));
1030
1031 if (rc) {
1032 pr_err("%s: copy config_tx from user; rc=%d\n",
1033 __func__, rc);
1034 return -EFAULT;
1035 }
1036
1037 if (config_tx.us_xx_info.params_data_size > USF_MAX_USER_BUF_SIZE) {
1038 pr_err("%s: user buffer size exceeds maximum\n",
1039 __func__);
1040 return -EFAULT;
1041 }
1042
1043 return __usf_set_tx_info(usf, &config_tx);
1044} /* usf_set_tx_info */
1045
1046static int __usf_set_rx_info(struct usf_type *usf,
1047 struct us_rx_info_type *config_rx)
1048{
1049 struct usf_xx_type *usf_xx = &usf->usf_rx;
1050 int rc = 0;
1051
1052 usf_xx->new_region = USM_UNDEF_TOKEN;
1053 usf_xx->prev_region = USM_UNDEF_TOKEN;
1054
1055 usf_xx->cb = usf_rx_cb;
1056
1057 rc = config_xx(usf_xx, &(config_rx->us_xx_info));
1058 if (rc)
1059 return rc;
1060
1061 rc = q6usm_open_write(usf_xx->usc,
1062 usf_xx->encdec_cfg.format_id);
1063 if (rc)
1064 return rc;
1065
1066 rc = q6usm_us_client_buf_alloc(
1067 IN,
1068 usf_xx->usc,
1069 usf_xx->buffer_size,
1070 usf_xx->buffer_count);
1071 if (rc) {
1072 (void)q6usm_cmd(usf_xx->usc, CMD_CLOSE);
1073 return rc;
1074 }
1075
1076 rc = q6usm_us_param_buf_alloc(IN, usf_xx->usc,
1077 config_rx->us_xx_info.max_get_set_param_buf_size);
1078 if (rc) {
1079 (void)q6usm_cmd(usf_xx->usc, CMD_CLOSE);
1080 return rc;
1081 }
1082
1083 rc = q6usm_dec_cfg_blk(usf_xx->usc,
1084 &usf_xx->encdec_cfg);
1085 if (rc)
1086 (void)q6usm_cmd(usf_xx->usc, CMD_CLOSE);
1087 else {
1088 init_waitqueue_head(&usf_xx->wait);
1089 usf_xx->usf_state = USF_CONFIGURED_STATE;
1090 }
1091
1092 return rc;
1093} /* __usf_set_rx_info */
1094
1095static int usf_set_rx_info(struct usf_type *usf, unsigned long arg)
1096{
1097 struct us_rx_info_type config_rx;
1098
1099 int rc = copy_from_user(&config_rx,
1100 (struct us_rx_info_type __user *) arg,
1101 sizeof(config_rx));
1102
1103 if (rc) {
1104 pr_err("%s: copy config_rx from user; rc=%d\n",
1105 __func__, rc);
1106 return -EFAULT;
1107 }
1108
1109 if (config_rx.us_xx_info.params_data_size > USF_MAX_USER_BUF_SIZE) {
1110 pr_err("%s: user buffer size exceeds maximum\n",
1111 __func__);
1112 return -EFAULT;
1113 }
1114
1115 return __usf_set_rx_info(usf, &config_rx);
1116} /* usf_set_rx_info */
1117
1118static int __usf_get_tx_update(struct usf_type *usf,
1119 struct us_tx_update_info_type *upd_tx_info)
1120{
1121 unsigned long prev_jiffies = 0;
1122 uint32_t timeout = 0;
1123 struct usf_xx_type *usf_xx = &usf->usf_tx;
1124 int rc = 0;
1125
1126 if (!usf_xx->user_upd_info_na) {
1127 usf_set_event_filters(usf, upd_tx_info->event_filters);
1128 handle_input_event(usf,
1129 upd_tx_info->event_counter,
1130 upd_tx_info->event);
1131
1132 /* Release available regions */
1133 rc = q6usm_read(usf_xx->usc,
1134 upd_tx_info->free_region);
1135 if (rc)
1136 return rc;
1137 } else
1138 usf_xx->user_upd_info_na = 0;
1139
1140 /* Get data ready regions */
1141 if (upd_tx_info->timeout == USF_INFINITIVE_TIMEOUT) {
1142 rc = wait_event_interruptible(usf_xx->wait,
1143 (usf_xx->prev_region !=
1144 usf_xx->new_region) ||
1145 (usf_xx->usf_state !=
1146 USF_WORK_STATE));
1147 } else {
1148 if (upd_tx_info->timeout == USF_NO_WAIT_TIMEOUT)
1149 rc = (usf_xx->prev_region != usf_xx->new_region);
1150 else {
1151 prev_jiffies = jiffies;
1152 if (upd_tx_info->timeout == USF_DEFAULT_TIMEOUT) {
1153 timeout = USF_TIMEOUT_JIFFIES;
1154 rc = wait_event_timeout(
1155 usf_xx->wait,
1156 (usf_xx->prev_region !=
1157 usf_xx->new_region) ||
1158 (usf_xx->usf_state !=
1159 USF_WORK_STATE),
1160 timeout);
1161 } else {
1162 timeout = upd_tx_info->timeout * HZ;
1163 rc = wait_event_interruptible_timeout(
1164 usf_xx->wait,
1165 (usf_xx->prev_region !=
1166 usf_xx->new_region) ||
1167 (usf_xx->usf_state !=
1168 USF_WORK_STATE),
1169 timeout);
1170 }
1171 }
1172 if (!rc) {
1173 pr_debug("%s: timeout. prev_j=%lu; j=%lu\n",
1174 __func__, prev_jiffies, jiffies);
1175 pr_debug("%s: timeout. prev=%d; new=%d\n",
1176 __func__, usf_xx->prev_region,
1177 usf_xx->new_region);
1178 pr_debug("%s: timeout. free_region=%d;\n",
1179 __func__, upd_tx_info->free_region);
1180 if (usf_xx->prev_region ==
1181 usf_xx->new_region) {
1182 pr_err("%s:read data: timeout\n",
1183 __func__);
1184 return -ETIME;
1185 }
1186 }
1187 }
1188
1189 if ((usf_xx->usf_state != USF_WORK_STATE) ||
1190 (rc == -ERESTARTSYS)) {
1191 pr_err("%s: Get ready region failure; state[%d]; rc[%d]\n",
1192 __func__, usf_xx->usf_state, rc);
1193 return -EINTR;
1194 }
1195
1196 upd_tx_info->ready_region = usf_xx->new_region;
1197 usf_xx->prev_region = upd_tx_info->ready_region;
1198
1199 if (upd_tx_info->ready_region == USM_WRONG_TOKEN) {
1200 pr_err("%s: TX path corrupted; prev=%d\n",
1201 __func__, usf_xx->prev_region);
1202 return -EIO;
1203 }
1204
1205 return rc;
1206} /* __usf_get_tx_update */
1207
1208static int usf_get_tx_update(struct usf_type *usf, unsigned long arg)
1209{
1210 struct us_tx_update_info_type upd_tx_info;
1211
1212 int rc = copy_from_user(&upd_tx_info,
1213 (struct us_tx_update_info_type __user *) arg,
1214 sizeof(upd_tx_info));
1215
1216 if (rc < 0) {
1217 pr_err("%s: copy upd_tx_info from user; rc=%d\n",
1218 __func__, rc);
1219 return -EFAULT;
1220 }
1221
1222 rc = __usf_get_tx_update(usf, &upd_tx_info);
1223 if (rc < 0) {
1224 pr_err("%s: get tx update failed; rc=%d\n",
1225 __func__, rc);
1226 return rc;
1227 }
1228
1229 rc = copy_to_user((void __user *)arg,
1230 &upd_tx_info,
1231 sizeof(upd_tx_info));
1232 if (rc) {
1233 pr_err("%s: copy upd_tx_info to user; rc=%d\n",
1234 __func__, rc);
1235 rc = -EFAULT;
1236 }
1237
1238 return rc;
1239} /* usf_get_tx_update */
1240
1241static int __usf_set_rx_update(struct usf_xx_type *usf_xx,
1242 struct us_rx_update_info_type *upd_rx_info)
1243{
1244 int rc = 0;
1245
1246 /* Send available data regions */
1247 if (upd_rx_info->ready_region !=
1248 usf_xx->buffer_count) {
1249 rc = q6usm_write(
1250 usf_xx->usc,
1251 upd_rx_info->ready_region);
1252 if (rc)
1253 return rc;
1254 }
1255
1256 /* Get free regions */
1257 rc = wait_event_timeout(
1258 usf_xx->wait,
1259 !q6usm_is_write_buf_full(
1260 usf_xx->usc,
1261 &(upd_rx_info->free_region)) ||
1262 (usf_xx->usf_state == USF_IDLE_STATE),
1263 USF_TIMEOUT_JIFFIES);
1264
1265 if (!rc) {
1266 rc = -ETIME;
1267 pr_err("%s:timeout. wait for write buf not full\n",
1268 __func__);
1269 } else {
1270 if (usf_xx->usf_state !=
1271 USF_WORK_STATE) {
1272 pr_err("%s: RX: state[%d]\n",
1273 __func__,
1274 usf_xx->usf_state);
1275 rc = -EINTR;
1276 }
1277 }
1278
1279 return rc;
1280} /* __usf_set_rx_update */
1281
1282static int usf_set_rx_update(struct usf_xx_type *usf_xx, unsigned long arg)
1283{
1284 struct us_rx_update_info_type upd_rx_info;
1285
1286 int rc = copy_from_user(&upd_rx_info,
1287 (struct us_rx_update_info_type __user *) arg,
1288 sizeof(upd_rx_info));
1289
1290 if (rc) {
1291 pr_err("%s: copy upd_rx_info from user; rc=%d\n",
1292 __func__, rc);
1293 return -EFAULT;
1294 }
1295
1296 rc = __usf_set_rx_update(usf_xx, &upd_rx_info);
1297 if (rc < 0) {
1298 pr_err("%s: set rx update failed; rc=%d\n",
1299 __func__, rc);
1300 return rc;
1301 }
1302
1303 rc = copy_to_user((void __user *)arg,
1304 &upd_rx_info,
1305 sizeof(upd_rx_info));
1306 if (rc) {
1307 pr_err("%s: copy rx_info to user; rc=%d\n",
1308 __func__, rc);
1309 rc = -EFAULT;
1310 }
1311
1312 return rc;
1313} /* usf_set_rx_update */
1314
1315static void usf_release_input(struct usf_type *usf)
1316{
1317 uint16_t ind = 0;
1318
1319 usf_unregister_conflicting_events(
1320 usf->conflicting_event_types);
1321 usf->conflicting_event_types = 0;
1322 for (ind = 0; ind < USF_MAX_EVENT_IND; ++ind) {
1323 if (usf->input_ifs[ind] == NULL)
1324 continue;
1325 input_unregister_device(usf->input_ifs[ind]);
1326 usf->input_ifs[ind] = NULL;
1327 pr_debug("%s input_unregister_device[%s]\n",
1328 __func__,
1329 s_usf_input_devs[ind].input_dev_name);
1330 }
1331} /* usf_release_input */
1332
1333static int usf_stop_tx(struct usf_type *usf)
1334{
1335 struct usf_xx_type *usf_xx = &usf->usf_tx;
1336
1337 usf_release_input(usf);
1338 usf_disable(usf_xx);
1339
1340 return 0;
1341} /* usf_stop_tx */
1342
1343static int __usf_get_version(struct us_version_info_type *version_info)
1344{
1345 int rc = 0;
1346
1347 if (version_info->buf_size < sizeof(DRV_VERSION)) {
1348 pr_err("%s: buf_size (%d) < version string size (%zu)\n",
1349 __func__, version_info->buf_size, sizeof(DRV_VERSION));
1350 return -EINVAL;
1351 }
1352
1353 rc = copy_to_user((void __user *)(version_info->pbuf),
1354 DRV_VERSION,
1355 sizeof(DRV_VERSION));
1356 if (rc) {
1357 pr_err("%s: copy to version_info.pbuf; rc=%d\n",
1358 __func__, rc);
1359 rc = -EFAULT;
1360 }
1361
1362 return rc;
1363} /* __usf_get_version */
1364
1365static int usf_get_version(unsigned long arg)
1366{
1367 struct us_version_info_type version_info;
1368
1369 int rc = copy_from_user(&version_info,
1370 (struct us_version_info_type __user *) arg,
1371 sizeof(version_info));
1372
1373 if (rc) {
1374 pr_err("%s: copy version_info from user; rc=%d\n",
1375 __func__, rc);
1376 return -EFAULT;
1377 }
1378
1379 rc = __usf_get_version(&version_info);
1380 if (rc < 0) {
1381 pr_err("%s: get version failed; rc=%d\n",
1382 __func__, rc);
1383 return rc;
1384 }
1385
1386 rc = copy_to_user((void __user *)arg,
1387 &version_info,
1388 sizeof(version_info));
1389 if (rc) {
1390 pr_err("%s: copy version_info to user; rc=%d\n",
1391 __func__, rc);
1392 rc = -EFAULT;
1393 }
1394
1395 return rc;
1396} /* usf_get_version */
1397
1398static int __usf_set_stream_param(struct usf_xx_type *usf_xx,
1399 struct us_stream_param_type *set_stream_param,
1400 int dir)
1401{
1402 struct us_client *usc = usf_xx->usc;
1403 struct us_port_data *port;
1404 int rc = 0;
1405
1406 if (usc == NULL) {
1407 pr_err("%s: usc is null\n",
1408 __func__);
1409 return -EFAULT;
1410 }
1411
1412 port = &usc->port[dir];
1413 if (port == NULL) {
1414 pr_err("%s: port is null\n",
1415 __func__);
1416 return -EFAULT;
1417 }
1418
1419 if (port->param_buf == NULL) {
1420 pr_err("%s: parameter buffer is null\n",
1421 __func__);
1422 return -EFAULT;
1423 }
1424
1425 if (set_stream_param->buf_size > port->param_buf_size) {
1426 pr_err("%s: buf_size (%d) > maximum buf size (%d)\n",
1427 __func__, set_stream_param->buf_size,
1428 port->param_buf_size);
1429 return -EINVAL;
1430 }
1431
1432 if (set_stream_param->buf_size == 0) {
1433 pr_err("%s: buf_size is 0\n", __func__);
1434 return -EINVAL;
1435 }
1436
1437 rc = copy_from_user(port->param_buf,
1438 (uint8_t __user *) set_stream_param->pbuf,
1439 set_stream_param->buf_size);
1440 if (rc) {
1441 pr_err("%s: copy param buf from user; rc=%d\n",
1442 __func__, rc);
1443 return -EFAULT;
1444 }
1445
1446 rc = q6usm_set_us_stream_param(dir, usc, set_stream_param->module_id,
1447 set_stream_param->param_id,
1448 set_stream_param->buf_size);
1449 if (rc) {
1450 pr_err("%s: q6usm_set_us_stream_param failed; rc=%d\n",
1451 __func__, rc);
1452 return -EFAULT;
1453 }
1454
1455 return rc;
1456}
1457
1458static int usf_set_stream_param(struct usf_xx_type *usf_xx,
1459 unsigned long arg, int dir)
1460{
1461 struct us_stream_param_type set_stream_param;
1462 int rc = 0;
1463
1464 rc = copy_from_user(&set_stream_param,
1465 (struct us_stream_param_type __user *) arg,
1466 sizeof(set_stream_param));
1467
1468 if (rc) {
1469 pr_err("%s: copy set_stream_param from user; rc=%d\n",
1470 __func__, rc);
1471 return -EFAULT;
1472 }
1473
1474 return __usf_set_stream_param(usf_xx, &set_stream_param, dir);
1475} /* usf_set_stream_param */
1476
1477static int __usf_get_stream_param(struct usf_xx_type *usf_xx,
1478 struct us_stream_param_type *get_stream_param,
1479 int dir)
1480{
1481 struct us_client *usc = usf_xx->usc;
1482 struct us_port_data *port;
1483 int rc = 0;
1484
1485 if (usc == NULL) {
1486 pr_err("%s: us_client is null\n",
1487 __func__);
1488 return -EFAULT;
1489 }
1490
1491 port = &usc->port[dir];
1492
1493 if (port->param_buf == NULL) {
1494 pr_err("%s: parameter buffer is null\n",
1495 __func__);
1496 return -EFAULT;
1497 }
1498
1499 if (get_stream_param->buf_size > port->param_buf_size) {
1500 pr_err("%s: buf_size (%d) > maximum buf size (%d)\n",
1501 __func__, get_stream_param->buf_size,
1502 port->param_buf_size);
1503 return -EINVAL;
1504 }
1505
1506 if (get_stream_param->buf_size == 0) {
1507 pr_err("%s: buf_size is 0\n", __func__);
1508 return -EINVAL;
1509 }
1510
1511 rc = q6usm_get_us_stream_param(dir, usc, get_stream_param->module_id,
1512 get_stream_param->param_id,
1513 get_stream_param->buf_size);
1514 if (rc) {
1515 pr_err("%s: q6usm_get_us_stream_param failed; rc=%d\n",
1516 __func__, rc);
1517 return -EFAULT;
1518 }
1519
1520 rc = copy_to_user((uint8_t __user *) get_stream_param->pbuf,
1521 port->param_buf,
1522 get_stream_param->buf_size);
1523 if (rc) {
1524 pr_err("%s: copy param buf to user; rc=%d\n",
1525 __func__, rc);
1526 return -EFAULT;
1527 }
1528
1529 return rc;
1530}
1531
1532static int usf_get_stream_param(struct usf_xx_type *usf_xx,
1533 unsigned long arg, int dir)
1534{
1535 struct us_stream_param_type get_stream_param;
1536 int rc = 0;
1537
1538 rc = copy_from_user(&get_stream_param,
1539 (struct us_stream_param_type __user *) arg,
1540 sizeof(get_stream_param));
1541
1542 if (rc) {
1543 pr_err("%s: copy get_stream_param from user; rc=%d\n",
1544 __func__, rc);
1545 return -EFAULT;
1546 }
1547
1548 return __usf_get_stream_param(usf_xx, &get_stream_param, dir);
1549} /* usf_get_stream_param */
1550
1551static long __usf_ioctl(struct usf_type *usf,
1552 unsigned int cmd,
1553 unsigned long arg)
1554{
1555
1556 int rc = 0;
1557 struct usf_xx_type *usf_xx = NULL;
1558
1559 switch (cmd) {
1560 case US_START_TX: {
1561 usf_xx = &usf->usf_tx;
1562 if (usf_xx->usf_state == USF_CONFIGURED_STATE)
1563 rc = usf_start_tx(usf_xx);
1564 else {
1565 pr_err("%s: start_tx: wrong state[%d]\n",
1566 __func__,
1567 usf_xx->usf_state);
1568 return -EBADFD;
1569 }
1570 break;
1571 }
1572
1573 case US_START_RX: {
1574 usf_xx = &usf->usf_rx;
1575 if (usf_xx->usf_state == USF_CONFIGURED_STATE)
1576 rc = usf_start_rx(usf_xx);
1577 else {
1578 pr_err("%s: start_rx: wrong state[%d]\n",
1579 __func__,
1580 usf_xx->usf_state);
1581 return -EBADFD;
1582 }
1583 break;
1584 }
1585
1586 case US_SET_TX_INFO: {
1587 usf_xx = &usf->usf_tx;
1588 if (usf_xx->usf_state == USF_OPENED_STATE)
1589 rc = usf_set_tx_info(usf, arg);
1590 else {
1591 pr_err("%s: set_tx_info: wrong state[%d]\n",
1592 __func__,
1593 usf_xx->usf_state);
1594 return -EBADFD;
1595 }
1596
1597 break;
1598 } /* US_SET_TX_INFO */
1599
1600 case US_SET_RX_INFO: {
1601 usf_xx = &usf->usf_rx;
1602 if (usf_xx->usf_state == USF_OPENED_STATE)
1603 rc = usf_set_rx_info(usf, arg);
1604 else {
1605 pr_err("%s: set_rx_info: wrong state[%d]\n",
1606 __func__,
1607 usf_xx->usf_state);
1608 return -EBADFD;
1609 }
1610
1611 break;
1612 } /* US_SET_RX_INFO */
1613
1614 case US_GET_TX_UPDATE: {
1615 struct usf_xx_type *usf_xx = &usf->usf_tx;
1616
1617 if (usf_xx->usf_state == USF_WORK_STATE)
1618 rc = usf_get_tx_update(usf, arg);
1619 else {
1620 pr_err("%s: get_tx_update: wrong state[%d]\n", __func__,
1621 usf_xx->usf_state);
1622 rc = -EBADFD;
1623 }
1624 break;
1625 } /* US_GET_TX_UPDATE */
1626
1627 case US_SET_RX_UPDATE: {
1628 struct usf_xx_type *usf_xx = &usf->usf_rx;
1629
1630 if (usf_xx->usf_state == USF_WORK_STATE)
1631 rc = usf_set_rx_update(usf_xx, arg);
1632 else {
1633 pr_err("%s: set_rx_update: wrong state[%d]\n",
1634 __func__,
1635 usf_xx->usf_state);
1636 rc = -EBADFD;
1637 }
1638 break;
1639 } /* US_SET_RX_UPDATE */
1640
1641 case US_STOP_TX: {
1642 usf_xx = &usf->usf_tx;
1643 if ((usf_xx->usf_state == USF_WORK_STATE)
1644 || (usf_xx->usf_state == USF_ADSP_RESTART_STATE))
1645 rc = usf_stop_tx(usf);
1646 else {
1647 pr_err("%s: stop_tx: wrong state[%d]\n",
1648 __func__,
1649 usf_xx->usf_state);
1650 return -EBADFD;
1651 }
1652 break;
1653 } /* US_STOP_TX */
1654
1655 case US_STOP_RX: {
1656 usf_xx = &usf->usf_rx;
1657 if ((usf_xx->usf_state == USF_WORK_STATE)
1658 || (usf_xx->usf_state == USF_ADSP_RESTART_STATE))
1659 usf_disable(usf_xx);
1660 else {
1661 pr_err("%s: stop_rx: wrong state[%d]\n",
1662 __func__,
1663 usf_xx->usf_state);
1664 return -EBADFD;
1665 }
1666 break;
1667 } /* US_STOP_RX */
1668
1669 case US_SET_DETECTION: {
1670 struct usf_xx_type *usf_xx = &usf->usf_tx;
1671
1672 if (usf_xx->usf_state == USF_WORK_STATE)
1673 rc = usf_set_us_detection(usf, arg);
1674 else {
1675 pr_err("%s: set us detection: wrong state[%d]\n",
1676 __func__,
1677 usf_xx->usf_state);
1678 rc = -EBADFD;
1679 }
1680 break;
1681 } /* US_SET_DETECTION */
1682
1683 case US_GET_VERSION: {
1684 rc = usf_get_version(arg);
1685 break;
1686 } /* US_GET_VERSION */
1687
1688 case US_SET_TX_STREAM_PARAM: {
1689 rc = usf_set_stream_param(&usf->usf_tx, arg, OUT);
1690 break;
1691 } /* US_SET_TX_STREAM_PARAM */
1692
1693 case US_GET_TX_STREAM_PARAM: {
1694 rc = usf_get_stream_param(&usf->usf_tx, arg, OUT);
1695 break;
1696 } /* US_GET_TX_STREAM_PARAM */
1697
1698 case US_SET_RX_STREAM_PARAM: {
1699 rc = usf_set_stream_param(&usf->usf_rx, arg, IN);
1700 break;
1701 } /* US_SET_RX_STREAM_PARAM */
1702
1703 case US_GET_RX_STREAM_PARAM: {
1704 rc = usf_get_stream_param(&usf->usf_rx, arg, IN);
1705 break;
1706 } /* US_GET_RX_STREAM_PARAM */
1707
1708 default:
1709 pr_err("%s: unsupported IOCTL command [%d]\n",
1710 __func__,
1711 cmd);
1712 rc = -ENOTTY;
1713 break;
1714 }
1715
1716 if (rc &&
1717 ((cmd == US_SET_TX_INFO) ||
1718 (cmd == US_SET_RX_INFO)))
1719 release_xx(usf_xx);
1720
1721 return rc;
1722} /* __usf_ioctl */
1723
1724static long usf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1725{
1726 struct usf_type *usf = file->private_data;
1727 int rc = 0;
1728
1729 mutex_lock(&usf->mutex);
1730 rc = __usf_ioctl(usf, cmd, arg);
1731 mutex_unlock(&usf->mutex);
1732
1733 return rc;
1734} /* usf_ioctl */
1735
1736#ifdef CONFIG_COMPAT
1737
1738#define US_SET_TX_INFO32 _IOW(USF_IOCTL_MAGIC, 0, \
1739 struct us_tx_info_type32)
1740#define US_GET_TX_UPDATE32 _IOWR(USF_IOCTL_MAGIC, 2, \
1741 struct us_tx_update_info_type32)
1742#define US_SET_RX_INFO32 _IOW(USF_IOCTL_MAGIC, 3, \
1743 struct us_rx_info_type32)
1744#define US_SET_RX_UPDATE32 _IOWR(USF_IOCTL_MAGIC, 4, \
1745 struct us_rx_update_info_type32)
1746#define US_SET_DETECTION32 _IOWR(USF_IOCTL_MAGIC, 8, \
1747 struct us_detect_info_type32)
1748#define US_GET_VERSION32 _IOWR(USF_IOCTL_MAGIC, 9, \
1749 struct us_version_info_type32)
1750#define US_SET_TX_STREAM_PARAM32 _IOW(USF_IOCTL_MAGIC, 10, \
1751 struct us_stream_param_type32)
1752#define US_GET_TX_STREAM_PARAM32 _IOWR(USF_IOCTL_MAGIC, 11, \
1753 struct us_stream_param_type32)
1754#define US_SET_RX_STREAM_PARAM32 _IOW(USF_IOCTL_MAGIC, 12, \
1755 struct us_stream_param_type32)
1756#define US_GET_RX_STREAM_PARAM32 _IOWR(USF_IOCTL_MAGIC, 13, \
1757 struct us_stream_param_type32)
1758
1759/* Info structure common for TX and RX */
1760struct us_xx_info_type32 {
1761/* Input: general info */
1762/* Name of the client - event calculator, ptr to char */
1763 const compat_uptr_t client_name;
1764/* Selected device identification, accepted in the kernel's CAD */
1765 uint32_t dev_id;
1766/* 0 - point_epos type; (e.g. 1 - gr_mmrd) */
1767 uint32_t stream_format;
1768/* Required sample rate in Hz */
1769 uint32_t sample_rate;
1770/* Size of a buffer (bytes) for US data transfer between the module and USF */
1771 uint32_t buf_size;
1772/* Number of the buffers for the US data transfer */
1773 uint16_t buf_num;
1774/* Number of the microphones (TX) or speakers(RX) */
1775 uint16_t port_cnt;
1776/* Microphones(TX) or speakers(RX) indexes in their enumeration */
1777 uint8_t port_id[USF_MAX_PORT_NUM];
1778/* Bits per sample 16 or 32 */
1779 uint16_t bits_per_sample;
1780/* Input: Transparent info for encoder in the LPASS */
1781/* Parameters data size in bytes */
1782 uint16_t params_data_size;
1783/* Pointer to the parameters, ptr to uint8_t */
1784 compat_uptr_t params_data;
1785/* Max size of buffer for get and set parameter */
1786 uint32_t max_get_set_param_buf_size;
1787};
1788
1789struct us_tx_info_type32 {
1790/* Common info. This struct includes ptr and therefore the 32 version */
1791 struct us_xx_info_type32 us_xx_info;
1792/* Info specific for TX. This struct doesn't include long or ptr
1793 * and therefore no 32 version
1794 */
1795 struct us_input_info_type input_info;
1796};
1797
1798struct us_tx_update_info_type32 {
1799/* Input general: */
1800/* Number of calculated events */
1801 uint16_t event_counter;
1802/* Calculated events or NULL, ptr to struct usf_event_type */
1803 compat_uptr_t event;
1804/* Pointer (read index) to the end of available region */
1805/* in the shared US data memory */
1806 uint32_t free_region;
1807/* Time (sec) to wait for data or special values: */
1808/* USF_NO_WAIT_TIMEOUT, USF_INFINITIVE_TIMEOUT, USF_DEFAULT_TIMEOUT */
1809 uint32_t timeout;
1810/* Events (from conflicting devs) to be disabled/enabled */
1811 uint16_t event_filters;
1812
1813/* Input transparent data: */
1814/* Parameters size */
1815 uint16_t params_data_size;
1816/* Pointer to the parameters, ptr to uint8_t */
1817 compat_uptr_t params_data;
1818/* Output parameters: */
1819/* Pointer (write index) to the end of ready US data region */
1820/* in the shared memory */
1821 uint32_t ready_region;
1822};
1823
1824struct us_rx_info_type32 {
1825 /* Common info */
1826 struct us_xx_info_type32 us_xx_info;
1827 /* Info specific for RX*/
1828};
1829
1830struct us_rx_update_info_type32 {
1831/* Input general: */
1832/* Pointer (write index) to the end of ready US data region */
1833/* in the shared memory */
1834 uint32_t ready_region;
1835/* Input transparent data: */
1836/* Parameters size */
1837 uint16_t params_data_size;
1838/* pPointer to the parameters, ptr to uint8_t */
1839 compat_uptr_t params_data;
1840/* Output parameters: */
1841/* Pointer (read index) to the end of available region */
1842/* in the shared US data memory */
1843 uint32_t free_region;
1844};
1845
1846struct us_detect_info_type32 {
1847/* US detection place (HW|FW) */
1848/* NA in the Active and OFF states */
1849 enum us_detect_place_enum us_detector;
1850/* US detection mode */
1851 enum us_detect_mode_enum us_detect_mode;
1852/* US data dropped during this time (msec) */
1853 uint32_t skip_time;
1854/* Transparent data size */
1855 uint16_t params_data_size;
1856/* Pointer to the transparent data, ptr to uint8_t */
1857 compat_uptr_t params_data;
1858/* Time (sec) to wait for US presence event */
1859 uint32_t detect_timeout;
1860/* Out parameter: US presence */
1861 bool is_us;
1862};
1863
1864struct us_version_info_type32 {
1865/* Size of memory for the version string */
1866 uint16_t buf_size;
1867/* Pointer to the memory for the version string, ptr to char */
1868 compat_uptr_t pbuf;
1869};
1870
1871struct us_stream_param_type32 {
1872/* Id of module */
1873 uint32_t module_id;
1874/* Id of parameter */
1875 uint32_t param_id;
1876/* Size of memory of the parameter buffer */
1877 uint32_t buf_size;
1878/* Pointer to the memory of the parameter buffer */
1879 compat_uptr_t pbuf;
1880};
1881
1882static void usf_compat_xx_info_type(struct us_xx_info_type32 *us_xx_info32,
1883 struct us_xx_info_type *us_xx_info)
1884{
1885 int i = 0;
1886
1887 us_xx_info->client_name = compat_ptr(us_xx_info32->client_name);
1888 us_xx_info->dev_id = us_xx_info32->dev_id;
1889 us_xx_info->stream_format = us_xx_info32->stream_format;
1890 us_xx_info->sample_rate = us_xx_info32->sample_rate;
1891 us_xx_info->buf_size = us_xx_info32->buf_size;
1892 us_xx_info->buf_num = us_xx_info32->buf_num;
1893 us_xx_info->port_cnt = us_xx_info32->port_cnt;
1894 for (i = 0; i < USF_MAX_PORT_NUM; i++)
1895 us_xx_info->port_id[i] = us_xx_info32->port_id[i];
1896 us_xx_info->bits_per_sample = us_xx_info32->bits_per_sample;
1897 us_xx_info->params_data_size = us_xx_info32->params_data_size;
1898 us_xx_info->params_data = compat_ptr(us_xx_info32->params_data);
1899 us_xx_info->max_get_set_param_buf_size =
1900 us_xx_info32->max_get_set_param_buf_size;
1901}
1902
1903static int usf_set_tx_info32(struct usf_type *usf, unsigned long arg)
1904{
1905 struct us_tx_info_type32 config_tx32;
1906 struct us_tx_info_type config_tx;
1907
1908 int rc = copy_from_user(&config_tx32,
1909 (struct us_tx_info_type32 __user *) arg,
1910 sizeof(config_tx32));
1911
1912 if (rc) {
1913 pr_err("%s: copy config_tx from user; rc=%d\n",
1914 __func__, rc);
1915 return -EFAULT;
1916 }
1917 memset(&config_tx, 0, sizeof(config_tx));
1918 usf_compat_xx_info_type(&(config_tx32.us_xx_info),
1919 &(config_tx.us_xx_info));
1920 config_tx.input_info = config_tx32.input_info;
1921
1922 return __usf_set_tx_info(usf, &config_tx);
1923} /* usf_set_tx_info 32*/
1924
1925static int usf_set_rx_info32(struct usf_type *usf, unsigned long arg)
1926{
1927 struct us_rx_info_type32 config_rx32;
1928 struct us_rx_info_type config_rx;
1929
1930 int rc = copy_from_user(&config_rx32,
1931 (struct us_rx_info_type32 __user *) arg,
1932 sizeof(config_rx32));
1933
1934 if (rc) {
1935 pr_err("%s: copy config_rx from user; rc=%d\n",
1936 __func__, rc);
1937 return -EFAULT;
1938 }
1939 memset(&config_rx, 0, sizeof(config_rx));
1940 usf_compat_xx_info_type(&(config_rx32.us_xx_info),
1941 &(config_rx.us_xx_info));
1942
1943 return __usf_set_rx_info(usf, &config_rx);
1944} /* usf_set_rx_info32 */
1945
1946static int usf_get_tx_update32(struct usf_type *usf, unsigned long arg)
1947{
1948 struct us_tx_update_info_type32 upd_tx_info32;
1949 struct us_tx_update_info_type upd_tx_info;
1950
1951 int rc = copy_from_user(&upd_tx_info32,
1952 (struct us_tx_update_info_type32 __user *) arg,
1953 sizeof(upd_tx_info32));
1954
1955 if (rc) {
1956 pr_err("%s: copy upd_tx_info32 from user; rc=%d\n",
1957 __func__, rc);
1958 return -EFAULT;
1959 }
1960
1961 memset(&upd_tx_info, 0, sizeof(upd_tx_info));
1962 upd_tx_info.event_counter = upd_tx_info32.event_counter;
1963 upd_tx_info.event = compat_ptr(upd_tx_info32.event);
1964 upd_tx_info.free_region = upd_tx_info32.free_region;
1965 upd_tx_info.timeout = upd_tx_info32.timeout;
1966 upd_tx_info.event_filters = upd_tx_info32.event_filters;
1967 upd_tx_info.params_data_size = upd_tx_info32.params_data_size;
1968 upd_tx_info.params_data = compat_ptr(upd_tx_info32.params_data);
1969 upd_tx_info.ready_region = upd_tx_info32.ready_region;
1970
1971 rc = __usf_get_tx_update(usf, &upd_tx_info);
1972 if (rc < 0) {
1973 pr_err("%s: get tx update failed; rc=%d\n",
1974 __func__, rc);
1975 return rc;
1976 }
1977
1978 /* Update only the fields that were changed */
1979 upd_tx_info32.ready_region = upd_tx_info.ready_region;
1980
1981 rc = copy_to_user((void __user *)arg, &upd_tx_info32,
1982 sizeof(upd_tx_info32));
1983 if (rc) {
1984 pr_err("%s: copy upd_tx_info32 to user; rc=%d\n",
1985 __func__, rc);
1986 rc = -EFAULT;
1987 }
1988
1989 return rc;
1990} /* usf_get_tx_update */
1991
1992static int usf_set_rx_update32(struct usf_xx_type *usf_xx, unsigned long arg)
1993{
1994 struct us_rx_update_info_type32 upd_rx_info32;
1995 struct us_rx_update_info_type upd_rx_info;
1996
1997 int rc = copy_from_user(&upd_rx_info32,
1998 (struct us_rx_update_info_type32 __user *) arg,
1999 sizeof(upd_rx_info32));
2000
2001 if (rc) {
2002 pr_err("%s: copy upd_rx_info32 from user; rc=%d\n",
2003 __func__, rc);
2004 return -EFAULT;
2005 }
2006
2007 memset(&upd_rx_info, 0, sizeof(upd_rx_info));
2008 upd_rx_info.ready_region = upd_rx_info32.ready_region;
2009 upd_rx_info.params_data_size = upd_rx_info32.params_data_size;
2010 upd_rx_info.params_data = compat_ptr(upd_rx_info32.params_data);
2011 upd_rx_info.free_region = upd_rx_info32.free_region;
2012
2013 rc = __usf_set_rx_update(usf_xx, &upd_rx_info);
2014 if (rc < 0) {
2015 pr_err("%s: set rx update failed; rc=%d\n",
2016 __func__, rc);
2017 return rc;
2018 }
2019
2020 /* Update only the fields that were changed */
2021 upd_rx_info32.free_region = upd_rx_info.free_region;
2022
2023 rc = copy_to_user((void __user *)arg,
2024 &upd_rx_info32,
2025 sizeof(upd_rx_info32));
2026 if (rc) {
2027 pr_err("%s: copy rx_info32 to user; rc=%d\n",
2028 __func__, rc);
2029 rc = -EFAULT;
2030 }
2031
2032 return rc;
2033} /* usf_set_rx_update32 */
2034
2035static int usf_set_us_detection32(struct usf_type *usf, unsigned long arg)
2036{
2037 struct us_detect_info_type32 detect_info32;
2038 struct us_detect_info_type detect_info;
2039
2040 int rc = copy_from_user(&detect_info32,
2041 (struct us_detect_info_type32 __user *) arg,
2042 sizeof(detect_info32));
2043
2044 if (rc) {
2045 pr_err("%s: copy detect_info32 from user; rc=%d\n",
2046 __func__, rc);
2047 return -EFAULT;
2048 }
2049
2050 if (detect_info32.params_data_size > USF_MAX_USER_BUF_SIZE) {
2051 pr_err("%s: user buffer size exceeds maximum\n",
2052 __func__);
2053 return -EFAULT;
2054 }
2055
2056 memset(&detect_info, 0, sizeof(detect_info));
2057 detect_info.us_detector = detect_info32.us_detector;
2058 detect_info.us_detect_mode = detect_info32.us_detect_mode;
2059 detect_info.skip_time = detect_info32.skip_time;
2060 detect_info.params_data_size = detect_info32.params_data_size;
2061 detect_info.params_data = compat_ptr(detect_info32.params_data);
2062 detect_info.detect_timeout = detect_info32.detect_timeout;
2063 detect_info.is_us = detect_info32.is_us;
2064
2065 rc = __usf_set_us_detection(usf, &detect_info);
2066 if (rc < 0) {
2067 pr_err("%s: set us detection failed; rc=%d\n",
2068 __func__, rc);
2069 return rc;
2070 }
2071
2072 /* Update only the fields that were changed */
2073 detect_info32.is_us = detect_info.is_us;
2074
2075 rc = copy_to_user((void __user *)arg,
2076 &detect_info32,
2077 sizeof(detect_info32));
2078 if (rc) {
2079 pr_err("%s: copy detect_info32 to user; rc=%d\n",
2080 __func__, rc);
2081 rc = -EFAULT;
2082 }
2083
2084 return rc;
2085} /* usf_set_us_detection32 */
2086
2087static int usf_get_version32(unsigned long arg)
2088{
2089 struct us_version_info_type32 version_info32;
2090 struct us_version_info_type version_info;
2091
2092 int rc = copy_from_user(&version_info32,
2093 (struct us_version_info_type32 __user *) arg,
2094 sizeof(version_info32));
2095
2096 if (rc) {
2097 pr_err("%s: copy version_info32 from user; rc=%d\n",
2098 __func__, rc);
2099 return -EFAULT;
2100 }
2101
2102 memset(&version_info, 0, sizeof(version_info));
2103 version_info.buf_size = version_info32.buf_size;
2104 version_info.pbuf = compat_ptr(version_info32.pbuf);
2105
2106 rc = __usf_get_version(&version_info);
2107 if (rc < 0) {
2108 pr_err("%s: get version failed; rc=%d\n",
2109 __func__, rc);
2110 return rc;
2111 }
2112
2113 /* None of the fields were changed */
2114
2115 rc = copy_to_user((void __user *)arg,
2116 &version_info32,
2117 sizeof(version_info32));
2118 if (rc) {
2119 pr_err("%s: copy version_info32 to user; rc=%d\n",
2120 __func__, rc);
2121 rc = -EFAULT;
2122 }
2123
2124 return rc;
2125} /* usf_get_version32 */
2126
2127static int usf_set_stream_param32(struct usf_xx_type *usf_xx,
2128 unsigned long arg, int dir)
2129{
2130 struct us_stream_param_type32 set_stream_param32;
2131 struct us_stream_param_type set_stream_param;
2132 int rc = 0;
2133
2134 rc = copy_from_user(&set_stream_param32,
2135 (struct us_stream_param_type32 __user *) arg,
2136 sizeof(set_stream_param32));
2137
2138 if (rc) {
2139 pr_err("%s: copy set_stream_param from user; rc=%d\n",
2140 __func__, rc);
2141 return -EFAULT;
2142 }
2143
2144 memset(&set_stream_param, 0, sizeof(set_stream_param));
2145 set_stream_param.module_id = set_stream_param32.module_id;
2146 set_stream_param.param_id = set_stream_param32.param_id;
2147 set_stream_param.buf_size = set_stream_param32.buf_size;
2148 set_stream_param.pbuf = compat_ptr(set_stream_param32.pbuf);
2149
2150 return __usf_set_stream_param(usf_xx, &set_stream_param, dir);
2151} /* usf_set_stream_param32 */
2152
2153static int usf_get_stream_param32(struct usf_xx_type *usf_xx,
2154 unsigned long arg, int dir)
2155{
2156 struct us_stream_param_type32 get_stream_param32;
2157 struct us_stream_param_type get_stream_param;
2158 int rc = 0;
2159
2160 rc = copy_from_user(&get_stream_param32,
2161 (struct us_stream_param_type32 __user *) arg,
2162 sizeof(get_stream_param32));
2163
2164 if (rc) {
2165 pr_err("%s: copy get_stream_param from user; rc=%d\n",
2166 __func__, rc);
2167 return -EFAULT;
2168 }
2169
2170 memset(&get_stream_param, 0, sizeof(get_stream_param));
2171 get_stream_param.module_id = get_stream_param32.module_id;
2172 get_stream_param.param_id = get_stream_param32.param_id;
2173 get_stream_param.buf_size = get_stream_param32.buf_size;
2174 get_stream_param.pbuf = compat_ptr(get_stream_param32.pbuf);
2175
2176 return __usf_get_stream_param(usf_xx, &get_stream_param, dir);
2177} /* usf_get_stream_param32 */
2178
2179static long __usf_compat_ioctl(struct usf_type *usf,
2180 unsigned int cmd,
2181 unsigned long arg)
2182{
2183 int rc = 0;
2184 struct usf_xx_type *usf_xx = NULL;
2185
2186 switch (cmd) {
2187 case US_START_TX:
2188 case US_START_RX:
2189 case US_STOP_TX:
2190 case US_STOP_RX: {
2191 return __usf_ioctl(usf, cmd, arg);
2192 }
2193
2194 case US_SET_TX_INFO32: {
2195 usf_xx = &usf->usf_tx;
2196 if (usf_xx->usf_state == USF_OPENED_STATE)
2197 rc = usf_set_tx_info32(usf, arg);
2198 else {
2199 pr_err("%s: set_tx_info32: wrong state[%d]\n",
2200 __func__,
2201 usf_xx->usf_state);
2202 return -EBADFD;
2203 }
2204
2205 break;
2206 } /* US_SET_TX_INFO32 */
2207
2208 case US_SET_RX_INFO32: {
2209 usf_xx = &usf->usf_rx;
2210 if (usf_xx->usf_state == USF_OPENED_STATE)
2211 rc = usf_set_rx_info32(usf, arg);
2212 else {
2213 pr_err("%s: set_rx_info32: wrong state[%d]\n",
2214 __func__,
2215 usf_xx->usf_state);
2216 return -EBADFD;
2217 }
2218
2219 break;
2220 } /* US_SET_RX_INFO32 */
2221
2222 case US_GET_TX_UPDATE32: {
2223 struct usf_xx_type *usf_xx = &usf->usf_tx;
2224
2225 if (usf_xx->usf_state == USF_WORK_STATE)
2226 rc = usf_get_tx_update32(usf, arg);
2227 else {
2228 pr_err("%s: get_tx_update32: wrong state[%d]\n",
2229 __func__,
2230 usf_xx->usf_state);
2231 rc = -EBADFD;
2232 }
2233 break;
2234 } /* US_GET_TX_UPDATE32 */
2235
2236 case US_SET_RX_UPDATE32: {
2237 struct usf_xx_type *usf_xx = &usf->usf_rx;
2238
2239 if (usf_xx->usf_state == USF_WORK_STATE)
2240 rc = usf_set_rx_update32(usf_xx, arg);
2241 else {
2242 pr_err("%s: set_rx_update: wrong state[%d]\n",
2243 __func__,
2244 usf_xx->usf_state);
2245 rc = -EBADFD;
2246 }
2247 break;
2248 } /* US_SET_RX_UPDATE32 */
2249
2250 case US_SET_DETECTION32: {
2251 struct usf_xx_type *usf_xx = &usf->usf_tx;
2252
2253 if (usf_xx->usf_state == USF_WORK_STATE)
2254 rc = usf_set_us_detection32(usf, arg);
2255 else {
2256 pr_err("%s: set us detection: wrong state[%d]\n",
2257 __func__,
2258 usf_xx->usf_state);
2259 rc = -EBADFD;
2260 }
2261 break;
2262 } /* US_SET_DETECTION32 */
2263
2264 case US_GET_VERSION32: {
2265 rc = usf_get_version32(arg);
2266 break;
2267 } /* US_GET_VERSION32 */
2268
2269 case US_SET_TX_STREAM_PARAM32: {
2270 rc = usf_set_stream_param32(&usf->usf_tx, arg, OUT);
2271 break;
2272 } /* US_SET_TX_STREAM_PARAM32 */
2273
2274 case US_GET_TX_STREAM_PARAM32: {
2275 rc = usf_get_stream_param32(&usf->usf_tx, arg, OUT);
2276 break;
2277 } /* US_GET_TX_STREAM_PARAM32 */
2278
2279 case US_SET_RX_STREAM_PARAM32: {
2280 rc = usf_set_stream_param32(&usf->usf_rx, arg, IN);
2281 break;
2282 } /* US_SET_RX_STREAM_PARAM32 */
2283
2284 case US_GET_RX_STREAM_PARAM32: {
2285 rc = usf_get_stream_param32(&usf->usf_rx, arg, IN);
2286 break;
2287 } /* US_GET_RX_STREAM_PARAM32 */
2288
2289 default:
2290 pr_err("%s: unsupported IOCTL command [%d]\n",
2291 __func__,
2292 cmd);
2293 rc = -ENOTTY;
2294 break;
2295 }
2296
2297 if (rc &&
2298 ((cmd == US_SET_TX_INFO) ||
2299 (cmd == US_SET_RX_INFO)))
2300 release_xx(usf_xx);
2301
2302 return rc;
2303} /* __usf_compat_ioctl */
2304
2305static long usf_compat_ioctl(struct file *file,
2306 unsigned int cmd,
2307 unsigned long arg)
2308{
2309 struct usf_type *usf = file->private_data;
2310 int rc = 0;
2311
2312 mutex_lock(&usf->mutex);
2313 rc = __usf_compat_ioctl(usf, cmd, arg);
2314 mutex_unlock(&usf->mutex);
2315
2316 return rc;
2317} /* usf_compat_ioctl */
2318#endif /* CONFIG_COMPAT */
2319
2320static int usf_mmap(struct file *file, struct vm_area_struct *vms)
2321{
2322 struct usf_type *usf = file->private_data;
2323 int dir = OUT;
2324 struct usf_xx_type *usf_xx = &usf->usf_tx;
2325 int rc = 0;
2326
2327 mutex_lock(&usf->mutex);
2328 if (vms->vm_flags & USF_VM_WRITE) { /* RX buf mapping */
2329 dir = IN;
2330 usf_xx = &usf->usf_rx;
2331 }
2332 rc = q6usm_get_virtual_address(dir, usf_xx->usc, vms);
2333 mutex_unlock(&usf->mutex);
2334
2335 return rc;
2336}
2337
2338static uint16_t add_opened_dev(int minor)
2339{
2340 uint16_t ind = 0;
2341
2342 for (ind = 0; ind < MAX_DEVS_NUMBER; ++ind) {
2343 if (minor == atomic_cmpxchg(&s_opened_devs[ind], 0, minor)) {
2344 pr_err("%s: device %d is already opened\n",
2345 __func__, minor);
2346 return USF_UNDEF_DEV_ID;
2347 } else {
2348 pr_debug("%s: device %d is added; ind=%d\n",
2349 __func__, minor, ind);
2350 return ind;
2351 }
2352 }
2353
2354 pr_err("%s: there is no place for device %d\n",
2355 __func__, minor);
2356 return USF_UNDEF_DEV_ID;
2357}
2358
2359static int usf_open(struct inode *inode, struct file *file)
2360{
2361 struct usf_type *usf = NULL;
2362 uint16_t dev_ind = 0;
2363 int minor = MINOR(inode->i_rdev);
2364
2365 dev_ind = add_opened_dev(minor);
2366 if (dev_ind == USF_UNDEF_DEV_ID)
2367 return -EBUSY;
2368
2369 usf = kzalloc(sizeof(struct usf_type), GFP_KERNEL);
2370 if (usf == NULL)
2371 return -ENOMEM;
2372
2373 wakeup_source_init(&usf_wakeup_source, "usf");
2374
2375 file->private_data = usf;
2376 usf->dev_ind = dev_ind;
2377
2378 usf->usf_tx.usf_state = USF_OPENED_STATE;
2379 usf->usf_rx.usf_state = USF_OPENED_STATE;
2380
2381 usf->usf_tx.us_detect_type = USF_US_DETECT_UNDEF;
2382 usf->usf_rx.us_detect_type = USF_US_DETECT_UNDEF;
2383
2384 mutex_init(&usf->mutex);
2385
2386 pr_debug("%s:usf in open\n", __func__);
2387 return 0;
2388}
2389
2390static int usf_release(struct inode *inode, struct file *file)
2391{
2392 struct usf_type *usf = file->private_data;
2393
2394 pr_debug("%s: release entry\n", __func__);
2395
2396 mutex_lock(&usf->mutex);
2397 usf_release_input(usf);
2398
2399 usf_disable(&usf->usf_tx);
2400 usf_disable(&usf->usf_rx);
2401
2402 atomic_set(&s_opened_devs[usf->dev_ind], 0);
2403
2404 wakeup_source_trash(&usf_wakeup_source);
2405 mutex_unlock(&usf->mutex);
2406 mutex_destroy(&usf->mutex);
2407 kfree(usf);
2408 pr_debug("%s: release exit\n", __func__);
2409 return 0;
2410}
2411
2412extern long usf_compat_ioctl(struct file *file,
2413 unsigned int cmd,
2414 unsigned long arg);
2415
2416static const struct file_operations usf_fops = {
2417 .owner = THIS_MODULE,
2418 .open = usf_open,
2419 .release = usf_release,
2420 .unlocked_ioctl = usf_ioctl,
2421#ifdef CONFIG_COMPAT
2422 .compat_ioctl = usf_compat_ioctl,
2423#endif /* CONFIG_COMPAT */
2424 .mmap = usf_mmap,
2425};
2426
2427static struct miscdevice usf_misc[MAX_DEVS_NUMBER] = {
2428 {
2429 .minor = MISC_DYNAMIC_MINOR,
2430 .name = "usf1",
2431 .fops = &usf_fops,
2432 },
2433};
2434
2435static int __init usf_init(void)
2436{
2437 int rc = 0;
2438 uint16_t ind = 0;
2439
2440 pr_debug("%s: USF SW version %s.\n", __func__, DRV_VERSION);
2441 pr_debug("%s: Max %d devs registration\n", __func__, MAX_DEVS_NUMBER);
2442
2443 for (ind = 0; ind < MAX_DEVS_NUMBER; ++ind) {
2444 rc = misc_register(&usf_misc[ind]);
2445 if (rc) {
2446 pr_err("%s: misc_register() failed ind=%d; rc = %d\n",
2447 __func__, ind, rc);
2448 break;
2449 }
2450 }
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05302451 if (!rc) q6usm_init();
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302452
2453 return rc;
2454}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05302455module_init(usf_init);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302456
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05302457static void __exit usf_exit(void)
2458{
2459 uint16_t ind = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302460
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05302461 for (ind = 0; ind < MAX_DEVS_NUMBER; ++ind)
2462 misc_deregister(&usf_misc[ind]);
2463}
2464module_exit(usf_exit);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302465MODULE_DESCRIPTION("Ultrasound framework driver");
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05302466MODULE_LICENSE("GPL v2");