2 * Copyright (c) 2012 Hans Verkuil <hverkuil@xs4all.nl>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
16 #include <linux/kernel.h>
17 #include <linux/module.h>
18 #include <linux/init.h>
19 #include <linux/slab.h>
20 #include <linux/input.h>
21 #include <linux/videodev2.h>
22 #include <media/v4l2-device.h>
23 #include <media/v4l2-ioctl.h>
24 #include <media/v4l2-ctrls.h>
25 #include <media/v4l2-event.h>
26 #include <linux/usb.h>
27 #include <linux/mutex.h>
29 /* driver and module definitions */
30 MODULE_AUTHOR("Hans Verkuil <hverkuil@xs4all.nl>");
31 MODULE_DESCRIPTION("Keene FM Transmitter driver");
32 MODULE_LICENSE("GPL");
34 /* Actually, it advertises itself as a Logitech */
35 #define USB_KEENE_VENDOR 0x046d
36 #define USB_KEENE_PRODUCT 0x0a0e
38 /* Probably USB_TIMEOUT should be modified in module parameter */
39 #define BUFFER_LENGTH 8
40 #define USB_TIMEOUT 500
42 /* Frequency limits in MHz */
45 #define FREQ_MUL 16000U
47 /* USB Device ID List */
48 static struct usb_device_id usb_keene_device_table
[] = {
49 {USB_DEVICE_AND_INTERFACE_INFO(USB_KEENE_VENDOR
, USB_KEENE_PRODUCT
,
50 USB_CLASS_HID
, 0, 0) },
51 { } /* Terminating entry */
54 MODULE_DEVICE_TABLE(usb
, usb_keene_device_table
);
57 struct usb_device
*usbdev
;
58 struct usb_interface
*intf
;
59 struct video_device vdev
;
60 struct v4l2_device v4l2_dev
;
61 struct v4l2_ctrl_handler hdl
;
73 static inline struct keene_device
*to_keene_dev(struct v4l2_device
*v4l2_dev
)
75 return container_of(v4l2_dev
, struct keene_device
, v4l2_dev
);
78 /* Set frequency (if non-0), PA, mute and turn on/off the FM transmitter. */
79 static int keene_cmd_main(struct keene_device
*radio
, unsigned freq
, bool play
)
81 unsigned short freq_send
= freq
? (freq
- 76 * 16000) / 800 : 0;
84 radio
->buffer
[0] = 0x00;
85 radio
->buffer
[1] = 0x50;
86 radio
->buffer
[2] = (freq_send
>> 8) & 0xff;
87 radio
->buffer
[3] = freq_send
& 0xff;
88 radio
->buffer
[4] = radio
->pa
;
89 /* If bit 4 is set, then tune to the frequency.
90 If bit 3 is set, then unmute; if bit 2 is set, then mute.
91 If bit 1 is set, then enter idle mode; if bit 0 is set,
92 then enter transmit mode.
94 radio
->buffer
[5] = (radio
->muted
? 4 : 8) | (play
? 1 : 2) |
96 radio
->buffer
[6] = 0x00;
97 radio
->buffer
[7] = 0x00;
99 ret
= usb_control_msg(radio
->usbdev
, usb_sndctrlpipe(radio
->usbdev
, 0),
100 9, 0x21, 0x200, 2, radio
->buffer
, BUFFER_LENGTH
, USB_TIMEOUT
);
103 dev_warn(&radio
->vdev
.dev
, "%s failed (%d)\n", __func__
, ret
);
107 radio
->curfreq
= freq
;
111 /* Set TX, stereo and preemphasis mode (50 us vs 75 us). */
112 static int keene_cmd_set(struct keene_device
*radio
)
116 radio
->buffer
[0] = 0x00;
117 radio
->buffer
[1] = 0x51;
118 radio
->buffer
[2] = radio
->tx
;
119 /* If bit 0 is set, then transmit mono, otherwise stereo.
120 If bit 2 is set, then enable 75 us preemphasis, otherwise
122 radio
->buffer
[3] = (radio
->stereo
? 0 : 1) | (radio
->preemph_75_us
? 4 : 0);
123 radio
->buffer
[4] = 0x00;
124 radio
->buffer
[5] = 0x00;
125 radio
->buffer
[6] = 0x00;
126 radio
->buffer
[7] = 0x00;
128 ret
= usb_control_msg(radio
->usbdev
, usb_sndctrlpipe(radio
->usbdev
, 0),
129 9, 0x21, 0x200, 2, radio
->buffer
, BUFFER_LENGTH
, USB_TIMEOUT
);
132 dev_warn(&radio
->vdev
.dev
, "%s failed (%d)\n", __func__
, ret
);
138 /* Handle unplugging the device.
139 * We call video_unregister_device in any case.
140 * The last function called in this procedure is
141 * usb_keene_device_release.
143 static void usb_keene_disconnect(struct usb_interface
*intf
)
145 struct keene_device
*radio
= to_keene_dev(usb_get_intfdata(intf
));
147 mutex_lock(&radio
->lock
);
148 usb_set_intfdata(intf
, NULL
);
149 video_unregister_device(&radio
->vdev
);
150 v4l2_device_disconnect(&radio
->v4l2_dev
);
151 mutex_unlock(&radio
->lock
);
152 v4l2_device_put(&radio
->v4l2_dev
);
155 static int usb_keene_suspend(struct usb_interface
*intf
, pm_message_t message
)
157 struct keene_device
*radio
= to_keene_dev(usb_get_intfdata(intf
));
159 return keene_cmd_main(radio
, 0, false);
162 static int usb_keene_resume(struct usb_interface
*intf
)
164 struct keene_device
*radio
= to_keene_dev(usb_get_intfdata(intf
));
167 keene_cmd_set(radio
);
168 keene_cmd_main(radio
, radio
->curfreq
, true);
172 static int vidioc_querycap(struct file
*file
, void *priv
,
173 struct v4l2_capability
*v
)
175 struct keene_device
*radio
= video_drvdata(file
);
177 strlcpy(v
->driver
, "radio-keene", sizeof(v
->driver
));
178 strlcpy(v
->card
, "Keene FM Transmitter", sizeof(v
->card
));
179 usb_make_path(radio
->usbdev
, v
->bus_info
, sizeof(v
->bus_info
));
180 v
->device_caps
= V4L2_CAP_RADIO
| V4L2_CAP_MODULATOR
;
181 v
->capabilities
= v
->device_caps
| V4L2_CAP_DEVICE_CAPS
;
185 static int vidioc_g_modulator(struct file
*file
, void *priv
,
186 struct v4l2_modulator
*v
)
188 struct keene_device
*radio
= video_drvdata(file
);
193 strlcpy(v
->name
, "FM", sizeof(v
->name
));
194 v
->rangelow
= FREQ_MIN
* FREQ_MUL
;
195 v
->rangehigh
= FREQ_MAX
* FREQ_MUL
;
196 v
->txsubchans
= radio
->stereo
? V4L2_TUNER_SUB_STEREO
: V4L2_TUNER_SUB_MONO
;
197 v
->capability
= V4L2_TUNER_CAP_LOW
| V4L2_TUNER_CAP_STEREO
;
201 static int vidioc_s_modulator(struct file
*file
, void *priv
,
202 const struct v4l2_modulator
*v
)
204 struct keene_device
*radio
= video_drvdata(file
);
209 radio
->stereo
= (v
->txsubchans
== V4L2_TUNER_SUB_STEREO
);
210 return keene_cmd_set(radio
);
213 static int vidioc_s_frequency(struct file
*file
, void *priv
,
214 const struct v4l2_frequency
*f
)
216 struct keene_device
*radio
= video_drvdata(file
);
217 unsigned freq
= f
->frequency
;
219 if (f
->tuner
!= 0 || f
->type
!= V4L2_TUNER_RADIO
)
221 freq
= clamp(freq
, FREQ_MIN
* FREQ_MUL
, FREQ_MAX
* FREQ_MUL
);
222 return keene_cmd_main(radio
, freq
, true);
225 static int vidioc_g_frequency(struct file
*file
, void *priv
,
226 struct v4l2_frequency
*f
)
228 struct keene_device
*radio
= video_drvdata(file
);
232 f
->type
= V4L2_TUNER_RADIO
;
233 f
->frequency
= radio
->curfreq
;
237 static int keene_s_ctrl(struct v4l2_ctrl
*ctrl
)
239 static const u8 db2tx
[] = {
240 /* -15, -12, -9, -6, -3, 0 dB */
241 0x03, 0x13, 0x02, 0x12, 0x22, 0x32,
242 /* 3, 6, 9, 12, 15, 18 dB */
243 0x21, 0x31, 0x20, 0x30, 0x40, 0x50
245 struct keene_device
*radio
=
246 container_of(ctrl
->handler
, struct keene_device
, hdl
);
249 case V4L2_CID_AUDIO_MUTE
:
250 radio
->muted
= ctrl
->val
;
251 return keene_cmd_main(radio
, 0, true);
253 case V4L2_CID_TUNE_POWER_LEVEL
:
254 /* To go from dBuV to the register value we apply the
255 following formula: */
256 radio
->pa
= (ctrl
->val
- 71) * 100 / 62;
257 return keene_cmd_main(radio
, 0, true);
259 case V4L2_CID_TUNE_PREEMPHASIS
:
260 radio
->preemph_75_us
= ctrl
->val
== V4L2_PREEMPHASIS_75_uS
;
261 return keene_cmd_set(radio
);
263 case V4L2_CID_AUDIO_COMPRESSION_GAIN
:
264 radio
->tx
= db2tx
[(ctrl
->val
- (s32
)ctrl
->minimum
) / (s32
)ctrl
->step
];
265 return keene_cmd_set(radio
);
270 /* File system interface */
271 static const struct v4l2_file_operations usb_keene_fops
= {
272 .owner
= THIS_MODULE
,
273 .open
= v4l2_fh_open
,
274 .release
= v4l2_fh_release
,
275 .poll
= v4l2_ctrl_poll
,
276 .unlocked_ioctl
= video_ioctl2
,
279 static const struct v4l2_ctrl_ops keene_ctrl_ops
= {
280 .s_ctrl
= keene_s_ctrl
,
283 static const struct v4l2_ioctl_ops usb_keene_ioctl_ops
= {
284 .vidioc_querycap
= vidioc_querycap
,
285 .vidioc_g_modulator
= vidioc_g_modulator
,
286 .vidioc_s_modulator
= vidioc_s_modulator
,
287 .vidioc_g_frequency
= vidioc_g_frequency
,
288 .vidioc_s_frequency
= vidioc_s_frequency
,
289 .vidioc_log_status
= v4l2_ctrl_log_status
,
290 .vidioc_subscribe_event
= v4l2_ctrl_subscribe_event
,
291 .vidioc_unsubscribe_event
= v4l2_event_unsubscribe
,
294 static void usb_keene_video_device_release(struct v4l2_device
*v4l2_dev
)
296 struct keene_device
*radio
= to_keene_dev(v4l2_dev
);
298 /* free rest memory */
299 v4l2_ctrl_handler_free(&radio
->hdl
);
300 kfree(radio
->buffer
);
304 /* check if the device is present and register with v4l and usb if it is */
305 static int usb_keene_probe(struct usb_interface
*intf
,
306 const struct usb_device_id
*id
)
308 struct usb_device
*dev
= interface_to_usbdev(intf
);
309 struct keene_device
*radio
;
310 struct v4l2_ctrl_handler
*hdl
;
314 * The Keene FM transmitter USB device has the same USB ID as
315 * the Logitech AudioHub Speaker, but it should ignore the hid.
316 * Check if the name is that of the Keene device.
317 * If not, then someone connected the AudioHub and we shouldn't
318 * attempt to handle this driver.
319 * For reference: the product name of the AudioHub is
320 * "AudioHub Speaker".
322 if (dev
->product
&& strcmp(dev
->product
, "B-LINK USB Audio "))
325 radio
= kzalloc(sizeof(struct keene_device
), GFP_KERNEL
);
327 radio
->buffer
= kmalloc(BUFFER_LENGTH
, GFP_KERNEL
);
329 if (!radio
|| !radio
->buffer
) {
330 dev_err(&intf
->dev
, "kmalloc for keene_device failed\n");
337 v4l2_ctrl_handler_init(hdl
, 4);
338 v4l2_ctrl_new_std(hdl
, &keene_ctrl_ops
, V4L2_CID_AUDIO_MUTE
,
340 v4l2_ctrl_new_std_menu(hdl
, &keene_ctrl_ops
, V4L2_CID_TUNE_PREEMPHASIS
,
341 V4L2_PREEMPHASIS_75_uS
, 1, V4L2_PREEMPHASIS_50_uS
);
342 v4l2_ctrl_new_std(hdl
, &keene_ctrl_ops
, V4L2_CID_TUNE_POWER_LEVEL
,
344 v4l2_ctrl_new_std(hdl
, &keene_ctrl_ops
, V4L2_CID_AUDIO_COMPRESSION_GAIN
,
348 radio
->stereo
= true;
352 v4l2_ctrl_handler_free(hdl
);
355 retval
= v4l2_device_register(&intf
->dev
, &radio
->v4l2_dev
);
357 dev_err(&intf
->dev
, "couldn't register v4l2_device\n");
361 mutex_init(&radio
->lock
);
363 radio
->v4l2_dev
.ctrl_handler
= hdl
;
364 radio
->v4l2_dev
.release
= usb_keene_video_device_release
;
365 strlcpy(radio
->vdev
.name
, radio
->v4l2_dev
.name
,
366 sizeof(radio
->vdev
.name
));
367 radio
->vdev
.v4l2_dev
= &radio
->v4l2_dev
;
368 radio
->vdev
.fops
= &usb_keene_fops
;
369 radio
->vdev
.ioctl_ops
= &usb_keene_ioctl_ops
;
370 radio
->vdev
.lock
= &radio
->lock
;
371 radio
->vdev
.release
= video_device_release_empty
;
372 radio
->vdev
.vfl_dir
= VFL_DIR_TX
;
374 radio
->usbdev
= interface_to_usbdev(intf
);
376 usb_set_intfdata(intf
, &radio
->v4l2_dev
);
378 video_set_drvdata(&radio
->vdev
, radio
);
380 /* at least 11ms is needed in order to settle hardware */
382 keene_cmd_main(radio
, 95.16 * FREQ_MUL
, false);
384 retval
= video_register_device(&radio
->vdev
, VFL_TYPE_RADIO
, -1);
386 dev_err(&intf
->dev
, "could not register video device\n");
389 v4l2_ctrl_handler_setup(hdl
);
390 dev_info(&intf
->dev
, "V4L2 device registered as %s\n",
391 video_device_node_name(&radio
->vdev
));
395 v4l2_device_unregister(&radio
->v4l2_dev
);
397 kfree(radio
->buffer
);
403 /* USB subsystem interface */
404 static struct usb_driver usb_keene_driver
= {
405 .name
= "radio-keene",
406 .probe
= usb_keene_probe
,
407 .disconnect
= usb_keene_disconnect
,
408 .id_table
= usb_keene_device_table
,
409 .suspend
= usb_keene_suspend
,
410 .resume
= usb_keene_resume
,
411 .reset_resume
= usb_keene_resume
,
414 module_usb_driver(usb_keene_driver
);