Lines Matching +full:cmd +full:- +full:gpios
1 // SPDX-License-Identifier: GPL-2.0
3 * Rockchip driver for IR-Cuter
17 #include <media/v4l2-subdev.h>
18 #include <media/v4l2-ctrls.h>
19 #include <media/v4l2-device.h>
22 #include <linux/rk-camera-module.h>
44 void (*ctrl)(struct ircut_dev *ircut, int cmd);
67 ((ircut->state == (expected)) ? true : false)
71 ircut->open_gpio = devm_gpiod_get(ircut->dev, "ircut-open", GPIOD_OUT_HIGH); in ap1511a_parse_dt()
72 if (IS_ERR(ircut->open_gpio)) { in ap1511a_parse_dt()
73 dev_err(ircut->dev, "Failed to get ircut-open-gpios\n"); in ap1511a_parse_dt()
74 return PTR_ERR(ircut->open_gpio); in ap1511a_parse_dt()
77 ircut->led_gpio = devm_gpiod_get_optional(ircut->dev, "led", GPIOD_OUT_LOW); in ap1511a_parse_dt()
78 if (IS_ERR(ircut->led_gpio)) in ap1511a_parse_dt()
79 dev_err(ircut->dev, "Failed to get led-gpios\n"); in ap1511a_parse_dt()
84 static void ap1511a_ctrl(struct ircut_dev *ircut, int cmd) in ap1511a_ctrl() argument
86 if (cmd > 0) { in ap1511a_ctrl()
87 gpiod_set_value_cansleep(ircut->open_gpio, 1); in ap1511a_ctrl()
88 if (!IS_ERR(ircut->led_gpio)) in ap1511a_ctrl()
89 gpiod_set_value_cansleep(ircut->led_gpio, 0); in ap1511a_ctrl()
91 gpiod_set_value_cansleep(ircut->open_gpio, 0); in ap1511a_ctrl()
92 if (!IS_ERR(ircut->led_gpio)) in ap1511a_ctrl()
93 gpiod_set_value_cansleep(ircut->led_gpio, 1); in ap1511a_ctrl()
101 dev_dbg(ircut->dev, "ircut_gpio_parse_dt"); in ba6208_parse_dt()
103 "rockchip,pulse-width", in ba6208_parse_dt()
104 &ircut->pulse_width); in ba6208_parse_dt()
106 ircut->pulse_width = 100; in ba6208_parse_dt()
107 dev_err(ircut->dev, in ba6208_parse_dt()
108 "failed get pulse-width,use dafult value 100\n"); in ba6208_parse_dt()
110 if (ircut->pulse_width > 2000) { in ba6208_parse_dt()
111 ircut->pulse_width = 300; in ba6208_parse_dt()
112 dev_info(ircut->dev, in ba6208_parse_dt()
115 dev_dbg(ircut->dev, "pulse-width value from dts %d\n", in ba6208_parse_dt()
116 ircut->pulse_width); in ba6208_parse_dt()
118 ircut->open_gpio = devm_gpiod_get(ircut->dev, "ircut-open", GPIOD_OUT_LOW); in ba6208_parse_dt()
119 if (IS_ERR(ircut->open_gpio)) in ba6208_parse_dt()
120 dev_err(ircut->dev, "Failed to get ircut-open-gpios\n"); in ba6208_parse_dt()
123 ircut->close_gpio = devm_gpiod_get(ircut->dev, in ba6208_parse_dt()
124 "ircut-close", GPIOD_OUT_LOW); in ba6208_parse_dt()
125 if (IS_ERR(ircut->close_gpio)) in ba6208_parse_dt()
126 dev_err(ircut->dev, "Failed to get ircut-close-gpios\n"); in ba6208_parse_dt()
129 ircut->led_gpio = devm_gpiod_get_optional(ircut->dev, "led", GPIOD_OUT_LOW); in ba6208_parse_dt()
130 if (IS_ERR(ircut->led_gpio)) in ba6208_parse_dt()
131 dev_err(ircut->dev, "Failed to get led-gpios\n"); in ba6208_parse_dt()
136 static void ba6208_ctrl(struct ircut_dev *ircut, int cmd) in ba6208_ctrl() argument
138 if (cmd > 0) { in ba6208_ctrl()
139 if (!IS_ERR(ircut->open_gpio)) in ba6208_ctrl()
140 gpiod_set_value_cansleep(ircut->open_gpio, 1); in ba6208_ctrl()
141 msleep(ircut->pulse_width); in ba6208_ctrl()
142 if (!IS_ERR(ircut->open_gpio)) in ba6208_ctrl()
143 gpiod_set_value_cansleep(ircut->open_gpio, 0); in ba6208_ctrl()
144 if (!IS_ERR(ircut->led_gpio)) in ba6208_ctrl()
145 gpiod_set_value_cansleep(ircut->led_gpio, 0); in ba6208_ctrl()
147 if (!IS_ERR(ircut->close_gpio)) in ba6208_ctrl()
148 gpiod_set_value_cansleep(ircut->close_gpio, 1); in ba6208_ctrl()
149 msleep(ircut->pulse_width); in ba6208_ctrl()
150 if (!IS_ERR(ircut->close_gpio)) in ba6208_ctrl()
151 gpiod_set_value_cansleep(ircut->close_gpio, 0); in ba6208_ctrl()
152 if (!IS_ERR(ircut->led_gpio)) in ba6208_ctrl()
153 gpiod_set_value_cansleep(ircut->led_gpio, 1); in ba6208_ctrl()
161 struct ircut_dev *ircut = wk->dev; in ircut_op_work()
164 if (ircut->drv_data->ctrl) in ircut_op_work()
165 ircut->drv_data->ctrl(ircut, wk->op_cmd); in ircut_op_work()
167 state = (wk->op_cmd > 0) ? IRCUT_STATE_OPENED : IRCUT_STATE_CLOSED; in ircut_op_work()
168 mutex_lock(&ircut->mut_state); in ircut_op_work()
169 complete(&ircut->complete); in ircut_op_work()
170 ircut->state = state; in ircut_op_work()
171 mutex_unlock(&ircut->mut_state); in ircut_op_work()
183 dev_dbg(ircut->dev, "%s, status %d\n", __func__, op); in ircut_operation()
184 mutex_lock(&ircut->mut_state); in ircut_operation()
185 old_state = ircut->state; in ircut_operation()
211 mutex_unlock(&ircut->mut_state); in ircut_operation()
215 wait_for_completion(&ircut->complete); in ircut_operation()
219 dev_err(ircut->dev, "failed to alloc ircut work struct\n"); in ircut_operation()
222 wk->op_cmd = op; in ircut_operation()
223 wk->dev = ircut; in ircut_operation()
224 mutex_lock(&ircut->mut_state); in ircut_operation()
226 ircut->state = IRCUT_STATE_OPENING; in ircut_operation()
228 ircut->state = IRCUT_STATE_CLOSING; in ircut_operation()
229 reinit_completion(&ircut->complete); in ircut_operation()
230 mutex_unlock(&ircut->mut_state); in ircut_operation()
232 INIT_WORK(&wk->work, ircut_op_work); in ircut_operation()
233 if (!queue_work(ircut->wq, &wk->work)) { in ircut_operation()
234 dev_err(ircut->dev, "queue work failed\n"); in ircut_operation()
236 ircut->state = old_state; in ircut_operation()
242 return -1; in ircut_operation()
274 for (i--; i >= 0 ; i--) in add_sysfs_interfaces()
277 return -ENODEV; in add_sysfs_interfaces()
283 int ret = -EINVAL; in ircut_s_ctrl()
284 struct ircut_dev *ircut = container_of(ctrl->handler, in ircut_s_ctrl()
287 if (ctrl->id == V4L2_CID_BAND_STOP_FILTER) { in ircut_s_ctrl()
288 ret = ircut_operation(ircut, ctrl->val); in ircut_s_ctrl()
290 ircut->val = ctrl->val; in ircut_s_ctrl()
295 static long ircut_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) in ircut_ioctl() argument
297 return -EINVAL; in ircut_ioctl()
336 struct device_node *node = pdev->dev.of_node; in ircut_probe()
343 dev_info(&pdev->dev, "driver version: %02x.%02x.%02x", in ircut_probe()
347 ircut = devm_kzalloc(&pdev->dev, sizeof(*ircut), GFP_KERNEL); in ircut_probe()
349 dev_err(&pdev->dev, "alloc ircut failed\n"); in ircut_probe()
350 return -ENOMEM; in ircut_probe()
353 match = of_match_node(ircut_of_match, pdev->dev.of_node); in ircut_probe()
355 return -ENODEV; in ircut_probe()
357 ircut->drv_data = match->data; in ircut_probe()
360 &ircut->module_index); in ircut_probe()
362 &ircut->module_facing); in ircut_probe()
364 dev_err(&pdev->dev, in ircut_probe()
366 return -EINVAL; in ircut_probe()
368 ircut->dev = &pdev->dev; in ircut_probe()
369 mutex_init(&ircut->mut_state); in ircut_probe()
370 init_completion(&ircut->complete); in ircut_probe()
371 ircut->wq = alloc_workqueue("ircut wq", in ircut_probe()
373 v4l2_subdev_init(&ircut->sd, &ircut_subdev_ops); in ircut_probe()
374 ircut->sd.owner = pdev->dev.driver->owner; in ircut_probe()
375 ircut->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in ircut_probe()
376 ircut->sd.dev = &pdev->dev; in ircut_probe()
377 v4l2_set_subdevdata(&ircut->sd, pdev); in ircut_probe()
378 platform_set_drvdata(pdev, &ircut->sd); in ircut_probe()
380 handler = &ircut->ctrl_handler; in ircut_probe()
386 if (handler->error) { in ircut_probe()
387 ret = handler->error; in ircut_probe()
388 dev_err(&pdev->dev, "Failed to init controls(%d)\n", ret); in ircut_probe()
391 ircut->sd.ctrl_handler = handler; in ircut_probe()
392 ret = media_entity_pads_init(&ircut->sd.entity, 0, NULL); in ircut_probe()
396 if (ircut->drv_data->parse_dt) { in ircut_probe()
397 ret = ircut->drv_data->parse_dt(ircut, node); in ircut_probe()
402 sd = &ircut->sd; in ircut_probe()
403 sd->entity.function = MEDIA_ENT_F_LENS; in ircut_probe()
404 sd->entity.flags = 1; in ircut_probe()
407 if (strcmp(ircut->module_facing, "back") == 0) in ircut_probe()
412 snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s", in ircut_probe()
413 ircut->module_index, facing, in ircut_probe()
417 dev_err(&pdev->dev, "v4l2 async register subdev failed\n"); in ircut_probe()
421 ircut->val = 3; in ircut_probe()
423 add_sysfs_interfaces(ircut->dev); in ircut_probe()
425 dev_info(&pdev->dev, "probe successful!"); in ircut_probe()
430 v4l2_device_unregister_subdev(&ircut->sd); in ircut_probe()
431 media_entity_cleanup(&ircut->sd.entity); in ircut_probe()
442 if (ircut && ircut->wq) in ircut_drv_remove()
443 drain_workqueue(ircut->wq); in ircut_drv_remove()
446 v4l2_ctrl_handler_free(&ircut->ctrl_handler); in ircut_drv_remove()
447 media_entity_cleanup(&ircut->sd.entity); in ircut_drv_remove()
463 MODULE_ALIAS("platform:rockchip-ircut");