aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/radio/Kconfig10
-rw-r--r--drivers/media/radio/Makefile1
-rw-r--r--drivers/media/radio/radio-timb.c244
-rw-r--r--include/media/timb_radio.h36
4 files changed, 291 insertions, 0 deletions
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index e5f0d7a8dd0b..7a1b2d219592 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -441,4 +441,14 @@ config RADIO_TEF6862
441 To compile this driver as a module, choose M here: the 441 To compile this driver as a module, choose M here: the
442 module will be called TEF6862. 442 module will be called TEF6862.
443 443
444config RADIO_TIMBERDALE
445 tristate "Enable the Timberdale radio driver"
446 depends on MFD_TIMBERDALE && VIDEO_V4L2
447 select RADIO_TEF6862
448 select RADIO_SAA7706H
449 ---help---
450 This is a kind of umbrella driver for the Radio Tuner and DSP
451 found behind the Timberdale FPGA on the Russellville board.
452 Enabling this driver will automatically select the DSP and tuner.
453
444endif # RADIO_ADAPTERS 454endif # RADIO_ADAPTERS
diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
index f681dbfe9ef0..f615583b4837 100644
--- a/drivers/media/radio/Makefile
+++ b/drivers/media/radio/Makefile
@@ -25,5 +25,6 @@ obj-$(CONFIG_USB_MR800) += radio-mr800.o
25obj-$(CONFIG_RADIO_TEA5764) += radio-tea5764.o 25obj-$(CONFIG_RADIO_TEA5764) += radio-tea5764.o
26obj-$(CONFIG_RADIO_SAA7706H) += saa7706h.o 26obj-$(CONFIG_RADIO_SAA7706H) += saa7706h.o
27obj-$(CONFIG_RADIO_TEF6862) += tef6862.o 27obj-$(CONFIG_RADIO_TEF6862) += tef6862.o
28obj-$(CONFIG_RADIO_TIMBERDALE) += radio-timb.o
28 29
29EXTRA_CFLAGS += -Isound 30EXTRA_CFLAGS += -Isound
diff --git a/drivers/media/radio/radio-timb.c b/drivers/media/radio/radio-timb.c
new file mode 100644
index 000000000000..0de457f6e6eb
--- /dev/null
+++ b/drivers/media/radio/radio-timb.c
@@ -0,0 +1,244 @@
1/*
2 * radio-timb.c Timberdale FPGA Radio driver
3 * Copyright (c) 2009 Intel Corporation
4 *
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.
8 *
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.
13 *
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.
17 */
18
19#include <linux/version.h>
20#include <linux/io.h>
21#include <media/v4l2-ioctl.h>
22#include <media/v4l2-device.h>
23#include <linux/platform_device.h>
24#include <linux/interrupt.h>
25#include <linux/i2c.h>
26#include <media/timb_radio.h>
27
28#define DRIVER_NAME "timb-radio"
29
30struct timbradio {
31 struct timb_radio_platform_data pdata;
32 struct v4l2_subdev *sd_tuner;
33 struct v4l2_subdev *sd_dsp;
34 struct video_device video_dev;
35 struct v4l2_device v4l2_dev;
36};
37
38
39static int timbradio_vidioc_querycap(struct file *file, void *priv,
40 struct v4l2_capability *v)
41{
42 strlcpy(v->driver, DRIVER_NAME, sizeof(v->driver));
43 strlcpy(v->card, "Timberdale Radio", sizeof(v->card));
44 snprintf(v->bus_info, sizeof(v->bus_info), "platform:"DRIVER_NAME);
45 v->version = KERNEL_VERSION(0, 0, 1);
46 v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
47 return 0;
48}
49
50static int timbradio_vidioc_g_tuner(struct file *file, void *priv,
51 struct v4l2_tuner *v)
52{
53 struct timbradio *tr = video_drvdata(file);
54 return v4l2_subdev_call(tr->sd_tuner, tuner, g_tuner, v);
55}
56
57static int timbradio_vidioc_s_tuner(struct file *file, void *priv,
58 struct v4l2_tuner *v)
59{
60 struct timbradio *tr = video_drvdata(file);
61 return v4l2_subdev_call(tr->sd_tuner, tuner, s_tuner, v);
62}
63
64static int timbradio_vidioc_g_input(struct file *filp, void *priv,
65 unsigned int *i)
66{
67 *i = 0;
68 return 0;
69}
70
71static int timbradio_vidioc_s_input(struct file *filp, void *priv,
72 unsigned int i)
73{
74 return i ? -EINVAL : 0;
75}
76
77static int timbradio_vidioc_g_audio(struct file *file, void *priv,
78 struct v4l2_audio *a)
79{
80 a->index = 0;
81 strlcpy(a->name, "Radio", sizeof(a->name));
82 a->capability = V4L2_AUDCAP_STEREO;
83 return 0;
84}
85
86static int timbradio_vidioc_s_audio(struct file *file, void *priv,
87 struct v4l2_audio *a)
88{
89 return a->index ? -EINVAL : 0;
90}
91
92static int timbradio_vidioc_s_frequency(struct file *file, void *priv,
93 struct v4l2_frequency *f)
94{
95 struct timbradio *tr = video_drvdata(file);
96 return v4l2_subdev_call(tr->sd_tuner, tuner, s_frequency, f);
97}
98
99static int timbradio_vidioc_g_frequency(struct file *file, void *priv,
100 struct v4l2_frequency *f)
101{
102 struct timbradio *tr = video_drvdata(file);
103 return v4l2_subdev_call(tr->sd_tuner, tuner, g_frequency, f);
104}
105
106static int timbradio_vidioc_queryctrl(struct file *file, void *priv,
107 struct v4l2_queryctrl *qc)
108{
109 struct timbradio *tr = video_drvdata(file);
110 return v4l2_subdev_call(tr->sd_dsp, core, queryctrl, qc);
111}
112
113static int timbradio_vidioc_g_ctrl(struct file *file, void *priv,
114 struct v4l2_control *ctrl)
115{
116 struct timbradio *tr = video_drvdata(file);
117 return v4l2_subdev_call(tr->sd_dsp, core, g_ctrl, ctrl);
118}
119
120static int timbradio_vidioc_s_ctrl(struct file *file, void *priv,
121 struct v4l2_control *ctrl)
122{
123 struct timbradio *tr = video_drvdata(file);
124 return v4l2_subdev_call(tr->sd_dsp, core, s_ctrl, ctrl);
125}
126
127static const struct v4l2_ioctl_ops timbradio_ioctl_ops = {
128 .vidioc_querycap = timbradio_vidioc_querycap,
129 .vidioc_g_tuner = timbradio_vidioc_g_tuner,
130 .vidioc_s_tuner = timbradio_vidioc_s_tuner,
131 .vidioc_g_frequency = timbradio_vidioc_g_frequency,
132 .vidioc_s_frequency = timbradio_vidioc_s_frequency,
133 .vidioc_g_input = timbradio_vidioc_g_input,
134 .vidioc_s_input = timbradio_vidioc_s_input,
135 .vidioc_g_audio = timbradio_vidioc_g_audio,
136 .vidioc_s_audio = timbradio_vidioc_s_audio,
137 .vidioc_queryctrl = timbradio_vidioc_queryctrl,
138 .vidioc_g_ctrl = timbradio_vidioc_g_ctrl,
139 .vidioc_s_ctrl = timbradio_vidioc_s_ctrl
140};
141
142static const struct v4l2_file_operations timbradio_fops = {
143 .owner = THIS_MODULE,
144 .ioctl = video_ioctl2,
145};
146
147static int __devinit timbradio_probe(struct platform_device *pdev)
148{
149 struct timb_radio_platform_data *pdata = pdev->dev.platform_data;
150 struct timbradio *tr;
151 int err;
152
153 if (!pdata) {
154 dev_err(&pdev->dev, "Platform data missing\n");
155 err = -EINVAL;
156 goto err;
157 }
158
159 tr = kzalloc(sizeof(*tr), GFP_KERNEL);
160 if (!tr) {
161 err = -ENOMEM;
162 goto err;
163 }
164
165 tr->pdata = *pdata;