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