2 * radio-timb.c Timberdale FPGA Radio driver
3 * Copyright (c) 2009 Intel Corporation
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
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.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 #include <linux/version.h>
21 #include <media/v4l2-ioctl.h>
22 #include <media/v4l2-device.h>
23 #include <linux/platform_device.h>
24 #include <linux/mfd/core.h>
25 #include <linux/interrupt.h>
26 #include <linux/slab.h>
27 #include <linux/i2c.h>
28 #include <media/timb_radio.h>
30 #define DRIVER_NAME "timb-radio"
33 struct timb_radio_platform_data pdata
;
34 struct v4l2_subdev
*sd_tuner
;
35 struct v4l2_subdev
*sd_dsp
;
36 struct video_device video_dev
;
37 struct v4l2_device v4l2_dev
;
42 static int timbradio_vidioc_querycap(struct file
*file
, void *priv
,
43 struct v4l2_capability
*v
)
45 strlcpy(v
->driver
, DRIVER_NAME
, sizeof(v
->driver
));
46 strlcpy(v
->card
, "Timberdale Radio", sizeof(v
->card
));
47 snprintf(v
->bus_info
, sizeof(v
->bus_info
), "platform:"DRIVER_NAME
);
48 v
->version
= KERNEL_VERSION(0, 0, 1);
49 v
->capabilities
= V4L2_CAP_TUNER
| V4L2_CAP_RADIO
;
53 static int timbradio_vidioc_g_tuner(struct file
*file
, void *priv
,
56 struct timbradio
*tr
= video_drvdata(file
);
57 return v4l2_subdev_call(tr
->sd_tuner
, tuner
, g_tuner
, v
);
60 static int timbradio_vidioc_s_tuner(struct file
*file
, void *priv
,
63 struct timbradio
*tr
= video_drvdata(file
);
64 return v4l2_subdev_call(tr
->sd_tuner
, tuner
, s_tuner
, v
);
67 static int timbradio_vidioc_g_input(struct file
*filp
, void *priv
,
74 static int timbradio_vidioc_s_input(struct file
*filp
, void *priv
,
77 return i
? -EINVAL
: 0;
80 static int timbradio_vidioc_g_audio(struct file
*file
, void *priv
,
84 strlcpy(a
->name
, "Radio", sizeof(a
->name
));
85 a
->capability
= V4L2_AUDCAP_STEREO
;
89 static int timbradio_vidioc_s_audio(struct file
*file
, void *priv
,
92 return a
->index
? -EINVAL
: 0;
95 static int timbradio_vidioc_s_frequency(struct file
*file
, void *priv
,
96 struct v4l2_frequency
*f
)
98 struct timbradio
*tr
= video_drvdata(file
);
99 return v4l2_subdev_call(tr
->sd_tuner
, tuner
, s_frequency
, f
);
102 static int timbradio_vidioc_g_frequency(struct file
*file
, void *priv
,
103 struct v4l2_frequency
*f
)
105 struct timbradio
*tr
= video_drvdata(file
);
106 return v4l2_subdev_call(tr
->sd_tuner
, tuner
, g_frequency
, f
);
109 static int timbradio_vidioc_queryctrl(struct file
*file
, void *priv
,
110 struct v4l2_queryctrl
*qc
)
112 struct timbradio
*tr
= video_drvdata(file
);
113 return v4l2_subdev_call(tr
->sd_dsp
, core
, queryctrl
, qc
);
116 static int timbradio_vidioc_g_ctrl(struct file
*file
, void *priv
,
117 struct v4l2_control
*ctrl
)
119 struct timbradio
*tr
= video_drvdata(file
);
120 return v4l2_subdev_call(tr
->sd_dsp
, core
, g_ctrl
, ctrl
);
123 static int timbradio_vidioc_s_ctrl(struct file
*file
, void *priv
,
124 struct v4l2_control
*ctrl
)
126 struct timbradio
*tr
= video_drvdata(file
);
127 return v4l2_subdev_call(tr
->sd_dsp
, core
, s_ctrl
, ctrl
);
130 static const struct v4l2_ioctl_ops timbradio_ioctl_ops
= {
131 .vidioc_querycap
= timbradio_vidioc_querycap
,
132 .vidioc_g_tuner
= timbradio_vidioc_g_tuner
,
133 .vidioc_s_tuner
= timbradio_vidioc_s_tuner
,
134 .vidioc_g_frequency
= timbradio_vidioc_g_frequency
,
135 .vidioc_s_frequency
= timbradio_vidioc_s_frequency
,
136 .vidioc_g_input
= timbradio_vidioc_g_input
,
137 .vidioc_s_input
= timbradio_vidioc_s_input
,
138 .vidioc_g_audio
= timbradio_vidioc_g_audio
,
139 .vidioc_s_audio
= timbradio_vidioc_s_audio
,
140 .vidioc_queryctrl
= timbradio_vidioc_queryctrl
,
141 .vidioc_g_ctrl
= timbradio_vidioc_g_ctrl
,
142 .vidioc_s_ctrl
= timbradio_vidioc_s_ctrl
145 static const struct v4l2_file_operations timbradio_fops
= {
146 .owner
= THIS_MODULE
,
147 .unlocked_ioctl
= video_ioctl2
,
150 static int __devinit
timbradio_probe(struct platform_device
*pdev
)
152 struct timb_radio_platform_data
*pdata
= mfd_get_data(pdev
);
153 struct timbradio
*tr
;
157 dev_err(&pdev
->dev
, "Platform data missing\n");
162 tr
= kzalloc(sizeof(*tr
), GFP_KERNEL
);
169 mutex_init(&tr
->lock
);
171 strlcpy(tr
->video_dev
.name
, "Timberdale Radio",
172 sizeof(tr
->video_dev
.name
));
173 tr
->video_dev
.fops
= &timbradio_fops
;
174 tr
->video_dev
.ioctl_ops
= &timbradio_ioctl_ops
;
175 tr
->video_dev
.release
= video_device_release_empty
;
176 tr
->video_dev
.minor
= -1;
177 tr
->video_dev
.lock
= &tr
->lock
;
179 strlcpy(tr
->v4l2_dev
.name
, DRIVER_NAME
, sizeof(tr
->v4l2_dev
.name
));
180 err
= v4l2_device_register(NULL
, &tr
->v4l2_dev
);
184 tr
->video_dev
.v4l2_dev
= &tr
->v4l2_dev
;
186 err
= video_register_device(&tr
->video_dev
, VFL_TYPE_RADIO
, -1);
188 dev_err(&pdev
->dev
, "Error reg video\n");
192 video_set_drvdata(&tr
->video_dev
, tr
);
194 platform_set_drvdata(pdev
, tr
);
198 video_device_release_empty(&tr
->video_dev
);
199 v4l2_device_unregister(&tr
->v4l2_dev
);
203 dev_err(&pdev
->dev
, "Failed to register: %d\n", err
);
208 static int __devexit
timbradio_remove(struct platform_device
*pdev
)
210 struct timbradio
*tr
= platform_get_drvdata(pdev
);
212 video_unregister_device(&tr
->video_dev
);
213 video_device_release_empty(&tr
->video_dev
);
215 v4l2_device_unregister(&tr
->v4l2_dev
);
222 static struct platform_driver timbradio_platform_driver
= {
225 .owner
= THIS_MODULE
,
227 .probe
= timbradio_probe
,
228 .remove
= timbradio_remove
,
231 /*--------------------------------------------------------------------------*/
233 static int __init
timbradio_init(void)
235 return platform_driver_register(&timbradio_platform_driver
);
238 static void __exit
timbradio_exit(void)
240 platform_driver_unregister(&timbradio_platform_driver
);
243 module_init(timbradio_init
);
244 module_exit(timbradio_exit
);
246 MODULE_DESCRIPTION("Timberdale Radio driver");
247 MODULE_AUTHOR("Mocean Laboratories <info@mocean-labs.com>");
248 MODULE_LICENSE("GPL v2");
249 MODULE_ALIAS("platform:"DRIVER_NAME
);