radio-sf16fmi.c (a3a9e287daa1f299e318161b790b1c5902b1d869) | radio-sf16fmi.c (4b8303747474033d6d73828607eafab77c620d96) |
---|---|
1/* SF16FMI radio driver for Linux radio support | 1/* SF16-FMI and SF16-FMP radio driver for Linux radio support |
2 * heavily based on rtrack driver... 3 * (c) 1997 M. Kirkwood 4 * (c) 1998 Petr Vandrovec, vandrove@vc.cvut.cz 5 * 6 * Fitted to new interface by Alan Cox <alan@lxorguk.ukuu.org.uk> 7 * Made working and cleaned up functions <mikael.hedin@irf.se> 8 * Support for ISAPnP by Ladislav Michl <ladis@psi.cz> 9 * 10 * Notes on the hardware 11 * 12 * Frequency control is done digitally -- ie out(port,encodefreq(95.8)); 13 * No volume control - only mute/unmute - you have to use line volume | 2 * heavily based on rtrack driver... 3 * (c) 1997 M. Kirkwood 4 * (c) 1998 Petr Vandrovec, vandrove@vc.cvut.cz 5 * 6 * Fitted to new interface by Alan Cox <alan@lxorguk.ukuu.org.uk> 7 * Made working and cleaned up functions <mikael.hedin@irf.se> 8 * Support for ISAPnP by Ladislav Michl <ladis@psi.cz> 9 * 10 * Notes on the hardware 11 * 12 * Frequency control is done digitally -- ie out(port,encodefreq(95.8)); 13 * No volume control - only mute/unmute - you have to use line volume |
14 * control on SB-part of SF16FMI | 14 * control on SB-part of SF16-FMI/SF16-FMP |
15 * 16 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> 17 */ 18 19#include <linux/version.h> 20#include <linux/kernel.h> /* __setup */ 21#include <linux/module.h> /* Modules */ 22#include <linux/init.h> /* Initdata */ 23#include <linux/ioport.h> /* request_region */ 24#include <linux/delay.h> /* udelay */ 25#include <linux/isapnp.h> 26#include <linux/mutex.h> 27#include <linux/videodev2.h> /* kernel radio structs */ 28#include <linux/io.h> /* outb, outb_p */ 29#include <media/v4l2-device.h> 30#include <media/v4l2-ioctl.h> 31 32MODULE_AUTHOR("Petr Vandrovec, vandrove@vc.cvut.cz and M. Kirkwood"); | 15 * 16 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> 17 */ 18 19#include <linux/version.h> 20#include <linux/kernel.h> /* __setup */ 21#include <linux/module.h> /* Modules */ 22#include <linux/init.h> /* Initdata */ 23#include <linux/ioport.h> /* request_region */ 24#include <linux/delay.h> /* udelay */ 25#include <linux/isapnp.h> 26#include <linux/mutex.h> 27#include <linux/videodev2.h> /* kernel radio structs */ 28#include <linux/io.h> /* outb, outb_p */ 29#include <media/v4l2-device.h> 30#include <media/v4l2-ioctl.h> 31 32MODULE_AUTHOR("Petr Vandrovec, vandrove@vc.cvut.cz and M. Kirkwood"); |
33MODULE_DESCRIPTION("A driver for the SF16MI radio."); | 33MODULE_DESCRIPTION("A driver for the SF16-FMI and SF16-FMP radio."); |
34MODULE_LICENSE("GPL"); 35 36static int io = -1; 37static int radio_nr = -1; 38 39module_param(io, int, 0); | 34MODULE_LICENSE("GPL"); 35 36static int io = -1; 37static int radio_nr = -1; 38 39module_param(io, int, 0); |
40MODULE_PARM_DESC(io, "I/O address of the SF16MI card (0x284 or 0x384)"); | 40MODULE_PARM_DESC(io, "I/O address of the SF16-FMI or SF16-FMP card (0x284 or 0x384)"); |
41module_param(radio_nr, int, 0); 42 43#define RADIO_VERSION KERNEL_VERSION(0, 0, 2) 44 45struct fmi 46{ 47 struct v4l2_device v4l2_dev; 48 struct video_device vdev; 49 int io; | 41module_param(radio_nr, int, 0); 42 43#define RADIO_VERSION KERNEL_VERSION(0, 0, 2) 44 45struct fmi 46{ 47 struct v4l2_device v4l2_dev; 48 struct video_device vdev; 49 int io; |
50 int curvol; /* 1 or 0 */ | 50 bool mute; |
51 unsigned long curfreq; /* freq in kHz */ 52 struct mutex lock; 53}; 54 55static struct fmi fmi_card; 56static struct pnp_dev *dev; 57 58/* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */ --- 41 unchanged lines hidden (view full) --- 100{ 101 mutex_lock(&fmi->lock); 102 fmi->curfreq = freq; 103 104 outbits(16, RSF16_ENCODE(freq), fmi->io); 105 outbits(8, 0xC0, fmi->io); 106 msleep(143); /* was schedule_timeout(HZ/7) */ 107 mutex_unlock(&fmi->lock); | 51 unsigned long curfreq; /* freq in kHz */ 52 struct mutex lock; 53}; 54 55static struct fmi fmi_card; 56static struct pnp_dev *dev; 57 58/* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */ --- 41 unchanged lines hidden (view full) --- 100{ 101 mutex_lock(&fmi->lock); 102 fmi->curfreq = freq; 103 104 outbits(16, RSF16_ENCODE(freq), fmi->io); 105 outbits(8, 0xC0, fmi->io); 106 msleep(143); /* was schedule_timeout(HZ/7) */ 107 mutex_unlock(&fmi->lock); |
108 if (fmi->curvol) | 108 if (!fmi->mute) |
109 fmi_unmute(fmi); 110 return 0; 111} 112 113static inline int fmi_getsigstr(struct fmi *fmi) 114{ 115 int val; 116 int res; 117 118 mutex_lock(&fmi->lock); | 109 fmi_unmute(fmi); 110 return 0; 111} 112 113static inline int fmi_getsigstr(struct fmi *fmi) 114{ 115 int val; 116 int res; 117 118 mutex_lock(&fmi->lock); |
119 val = fmi->curvol ? 0x08 : 0x00; /* unmute/mute */ | 119 val = fmi->mute ? 0x00 : 0x08; /* mute/unmute */ |
120 outb(val, fmi->io); 121 outb(val | 0x10, fmi->io); 122 msleep(143); /* was schedule_timeout(HZ/7) */ 123 res = (int)inb(fmi->io + 1); 124 outb(val, fmi->io); 125 126 mutex_unlock(&fmi->lock); 127 return (res & 2) ? 0 : 0xFFFF; --- 75 unchanged lines hidden (view full) --- 203 204static int vidioc_g_ctrl(struct file *file, void *priv, 205 struct v4l2_control *ctrl) 206{ 207 struct fmi *fmi = video_drvdata(file); 208 209 switch (ctrl->id) { 210 case V4L2_CID_AUDIO_MUTE: | 120 outb(val, fmi->io); 121 outb(val | 0x10, fmi->io); 122 msleep(143); /* was schedule_timeout(HZ/7) */ 123 res = (int)inb(fmi->io + 1); 124 outb(val, fmi->io); 125 126 mutex_unlock(&fmi->lock); 127 return (res & 2) ? 0 : 0xFFFF; --- 75 unchanged lines hidden (view full) --- 203 204static int vidioc_g_ctrl(struct file *file, void *priv, 205 struct v4l2_control *ctrl) 206{ 207 struct fmi *fmi = video_drvdata(file); 208 209 switch (ctrl->id) { 210 case V4L2_CID_AUDIO_MUTE: |
211 ctrl->value = fmi->curvol; | 211 ctrl->value = fmi->mute; |
212 return 0; 213 } 214 return -EINVAL; 215} 216 217static int vidioc_s_ctrl(struct file *file, void *priv, 218 struct v4l2_control *ctrl) 219{ 220 struct fmi *fmi = video_drvdata(file); 221 222 switch (ctrl->id) { 223 case V4L2_CID_AUDIO_MUTE: 224 if (ctrl->value) 225 fmi_mute(fmi); 226 else 227 fmi_unmute(fmi); | 212 return 0; 213 } 214 return -EINVAL; 215} 216 217static int vidioc_s_ctrl(struct file *file, void *priv, 218 struct v4l2_control *ctrl) 219{ 220 struct fmi *fmi = video_drvdata(file); 221 222 switch (ctrl->id) { 223 case V4L2_CID_AUDIO_MUTE: 224 if (ctrl->value) 225 fmi_mute(fmi); 226 else 227 fmi_unmute(fmi); |
228 fmi->curvol = ctrl->value; | 228 fmi->mute = ctrl->value; |
229 return 0; 230 } 231 return -EINVAL; 232} 233 234static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) 235{ 236 *i = 0; --- 145 unchanged lines hidden --- | 229 return 0; 230 } 231 return -EINVAL; 232} 233 234static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) 235{ 236 *i = 0; --- 145 unchanged lines hidden --- |