Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
9b76ede4
Commit
9b76ede4
authored
Feb 27, 2009
by
Mauro Carvalho Chehab
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
V4L/DVB (10771): tea575x-tuner: convert it to V4L2 API
Signed-off-by:
Mauro Carvalho Chehab
<
mchehab@redhat.com
>
parent
85f8841e
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
212 additions
and
100 deletions
+212
-100
include/sound/tea575x-tuner.h
include/sound/tea575x-tuner.h
+4
-4
sound/i2c/other/tea575x-tuner.c
sound/i2c/other/tea575x-tuner.c
+207
-95
sound/pci/Kconfig
sound/pci/Kconfig
+1
-1
No files found.
include/sound/tea575x-tuner.h
View file @
9b76ede4
...
...
@@ -22,8 +22,9 @@
*
*/
#include <linux/videodev.h>
#include <linux/videodev
2
.h>
#include <media/v4l2-dev.h>
#include <media/v4l2-ioctl.h>
struct
snd_tea575x
;
...
...
@@ -35,11 +36,10 @@ struct snd_tea575x_ops {
struct
snd_tea575x
{
struct
snd_card
*
card
;
struct
video_device
vd
;
/* video device */
struct
v4l2_file_operations
fops
;
struct
video_device
*
vd
;
/* video device */
int
dev_nr
;
/* requested device number + 1 */
int
vd_registered
;
/* video device is registered */
int
tea5759
;
/* 5759 chip is present */
int
mute
;
/* Device is muted? */
unsigned
int
freq_fixup
;
/* crystal onboard */
unsigned
int
val
;
/* hw value */
unsigned
long
freq
;
/* frequency */
...
...
sound/i2c/other/tea575x-tuner.c
View file @
9b76ede4
...
...
@@ -24,6 +24,7 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/version.h>
#include <sound/core.h>
#include <sound/tea575x-tuner.h>
...
...
@@ -31,6 +32,13 @@ MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION
(
"Routines for control of TEA5757/5759 Philips AM/FM radio tuner chips"
);
MODULE_LICENSE
(
"GPL"
);
static
int
radio_nr
=
-
1
;
module_param
(
radio_nr
,
int
,
0
);
#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
#define FREQ_LO (87 * 16000)
#define FREQ_HI (108 * 16000)
/*
* definitions
*/
...
...
@@ -53,6 +61,17 @@ MODULE_LICENSE("GPL");
#define TEA575X_BIT_DUMMY (1<<15)
/* buffer */
#define TEA575X_BIT_FREQ_MASK 0x7fff
static
struct
v4l2_queryctrl
radio_qctrl
[]
=
{
{
.
id
=
V4L2_CID_AUDIO_MUTE
,
.
name
=
"Mute"
,
.
minimum
=
0
,
.
maximum
=
1
,
.
default_value
=
1
,
.
type
=
V4L2_CTRL_TYPE_BOOLEAN
,
}
};
/*
* lowlevel part
*/
...
...
@@ -84,94 +103,146 @@ static void snd_tea575x_set_freq(struct snd_tea575x *tea)
* Linux Video interface
*/
static
long
snd_tea575x_ioctl
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
data
)
static
int
vidioc_querycap
(
struct
file
*
file
,
void
*
priv
,
struct
v4l2_capability
*
v
)
{
struct
snd_tea575x
*
tea
=
video_drvdata
(
file
);
void
__user
*
arg
=
(
void
__user
*
)
data
;
switch
(
cmd
)
{
case
VIDIOCGCAP
:
{
struct
video_capability
v
;
v
.
type
=
VID_TYPE_TUNER
;
v
.
channels
=
1
;
v
.
audios
=
1
;
/* No we don't do pictures */
v
.
maxwidth
=
0
;
v
.
maxheight
=
0
;
v
.
minwidth
=
0
;
v
.
minheight
=
0
;
strcpy
(
v
.
name
,
tea
->
tea5759
?
"TEA5759"
:
"TEA5757"
);
if
(
copy_to_user
(
arg
,
&
v
,
sizeof
(
v
)))
return
-
EFAULT
;
strcpy
(
v
->
card
,
tea
->
tea5759
?
"TEA5759"
:
"TEA5757"
);
strlcpy
(
v
->
driver
,
"tea575x-tuner"
,
sizeof
(
v
->
driver
));
strlcpy
(
v
->
card
,
"Maestro Radio"
,
sizeof
(
v
->
card
));
sprintf
(
v
->
bus_info
,
"PCI"
);
v
->
version
=
RADIO_VERSION
;
v
->
capabilities
=
V4L2_CAP_TUNER
;
return
0
;
}
case
VIDIOCGTUNER
:
{
struct
video_tuner
v
;
if
(
copy_from_user
(
&
v
,
arg
,
sizeof
(
v
))
!=
0
)
return
-
EFAULT
;
if
(
v
.
tuner
)
/* Only 1 tuner */
}
static
int
vidioc_g_tuner
(
struct
file
*
file
,
void
*
priv
,
struct
v4l2_tuner
*
v
)
{
if
(
v
->
index
>
0
)
return
-
EINVAL
;
v
.
rangelow
=
(
87
*
16000
);
v
.
rangehigh
=
(
108
*
16000
);
v
.
flags
=
VIDEO_TUNER_LOW
;
v
.
mode
=
VIDEO_MODE_AUTO
;
strcpy
(
v
.
name
,
"FM"
);
v
.
signal
=
0xFFFF
;
if
(
copy_to_user
(
arg
,
&
v
,
sizeof
(
v
)))
return
-
EFAULT
;
strcpy
(
v
->
name
,
"FM"
);
v
->
type
=
V4L2_TUNER_RADIO
;
v
->
rangelow
=
FREQ_LO
;
v
->
rangehigh
=
FREQ_HI
;
v
->
rxsubchans
=
V4L2_TUNER_SUB_MONO
|
V4L2_TUNER_SUB_STEREO
;
v
->
capability
=
V4L2_TUNER_CAP_LOW
;
v
->
audmode
=
V4L2_TUNER_MODE_MONO
;
v
->
signal
=
0xffff
;
return
0
;
}
case
VIDIOCSTUNER
:
{
struct
video_tuner
v
;
if
(
copy_from_user
(
&
v
,
arg
,
sizeof
(
v
)))
return
-
EFAULT
;
if
(
v
.
tuner
!=
0
)
}
static
int
vidioc_s_tuner
(
struct
file
*
file
,
void
*
priv
,
struct
v4l2_tuner
*
v
)
{
if
(
v
->
index
>
0
)
return
-
EINVAL
;
/* Only 1 tuner so no setting needed ! */
return
0
;
}
case
VIDIOCGFREQ
:
if
(
copy_to_user
(
arg
,
&
tea
->
freq
,
sizeof
(
tea
->
freq
)))
return
-
EFAULT
;
}
static
int
vidioc_g_frequency
(
struct
file
*
file
,
void
*
priv
,
struct
v4l2_frequency
*
f
)
{
struct
snd_tea575x
*
tea
=
video_drvdata
(
file
);
f
->
type
=
V4L2_TUNER_RADIO
;
f
->
frequency
=
tea
->
freq
;
return
0
;
case
VIDIOCSFREQ
:
if
(
copy_from_user
(
&
tea
->
freq
,
arg
,
sizeof
(
tea
->
freq
)))
return
-
EFAULT
;
}
static
int
vidioc_s_frequency
(
struct
file
*
file
,
void
*
priv
,
struct
v4l2_frequency
*
f
)
{
struct
snd_tea575x
*
tea
=
video_drvdata
(
file
);
if
(
f
->
frequency
<
FREQ_LO
||
f
->
frequency
>
FREQ_HI
)
return
-
EINVAL
;
tea
->
freq
=
f
->
frequency
;
snd_tea575x_set_freq
(
tea
);
return
0
;
case
VIDIOCGAUDIO
:
{
struct
video_audio
v
;
memset
(
&
v
,
0
,
sizeof
(
v
));
strcpy
(
v
.
name
,
"Radio"
);
if
(
copy_to_user
(
arg
,
&
v
,
sizeof
(
v
)))
return
-
EFAULT
;
}
static
int
vidioc_g_audio
(
struct
file
*
file
,
void
*
priv
,
struct
v4l2_audio
*
a
)
{
if
(
a
->
index
>
1
)
return
-
EINVAL
;
strcpy
(
a
->
name
,
"Radio"
);
a
->
capability
=
V4L2_AUDCAP_STEREO
;
return
0
;
}
static
int
vidioc_s_audio
(
struct
file
*
file
,
void
*
priv
,
struct
v4l2_audio
*
a
)
{
if
(
a
->
index
!=
0
)
return
-
EINVAL
;
return
0
;
}
static
int
vidioc_queryctrl
(
struct
file
*
file
,
void
*
priv
,
struct
v4l2_queryctrl
*
qc
)
{
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
radio_qctrl
);
i
++
)
{
if
(
qc
->
id
&&
qc
->
id
==
radio_qctrl
[
i
].
id
)
{
memcpy
(
qc
,
&
(
radio_qctrl
[
i
]),
sizeof
(
*
qc
));
return
0
;
}
case
VIDIOCSAUDIO
:
{
struct
video_audio
v
;
if
(
copy_from_user
(
&
v
,
arg
,
sizeof
(
v
)))
return
-
EFAULT
;
if
(
tea
->
ops
->
mute
)
tea
->
ops
->
mute
(
tea
,
(
v
.
flags
&
VIDEO_AUDIO_MUTE
)
?
1
:
0
);
if
(
v
.
audio
)
}
return
-
EINVAL
;
}
static
int
vidioc_g_ctrl
(
struct
file
*
file
,
void
*
priv
,
struct
v4l2_control
*
ctrl
)
{
struct
snd_tea575x
*
tea
=
video_drvdata
(
file
);
switch
(
ctrl
->
id
)
{
case
V4L2_CID_AUDIO_MUTE
:
if
(
tea
->
ops
->
mute
)
{
ctrl
->
value
=
tea
->
mute
;
return
0
;
}
}
return
-
EINVAL
;
}
static
int
vidioc_s_ctrl
(
struct
file
*
file
,
void
*
priv
,
struct
v4l2_control
*
ctrl
)
{
struct
snd_tea575x
*
tea
=
video_drvdata
(
file
);
switch
(
ctrl
->
id
)
{
case
V4L2_CID_AUDIO_MUTE
:
if
(
tea
->
ops
->
mute
)
{
tea
->
ops
->
mute
(
tea
,
ctrl
->
value
);
tea
->
mute
=
1
;
return
0
;
}
default:
return
-
ENOIOCTLCMD
;
}
return
-
EINVAL
;
}
static
void
snd_tea575x_release
(
struct
video_device
*
vfd
)
static
int
vidioc_g_input
(
struct
file
*
filp
,
void
*
priv
,
unsigned
int
*
i
)
{
*
i
=
0
;
return
0
;
}
static
int
vidioc_s_input
(
struct
file
*
filp
,
void
*
priv
,
unsigned
int
i
)
{
if
(
i
!=
0
)
return
-
EINVAL
;
return
0
;
}
static
int
snd_tea575x_exclusive_open
(
struct
file
*
file
)
...
...
@@ -189,50 +260,91 @@ static int snd_tea575x_exclusive_release(struct file *file)
return
0
;
}
static
const
struct
v4l2_file_operations
tea575x_fops
=
{
.
owner
=
THIS_MODULE
,
.
open
=
snd_tea575x_exclusive_open
,
.
release
=
snd_tea575x_exclusive_release
,
.
ioctl
=
video_ioctl2
,
};
static
const
struct
v4l2_ioctl_ops
tea575x_ioctl_ops
=
{
.
vidioc_querycap
=
vidioc_querycap
,
.
vidioc_g_tuner
=
vidioc_g_tuner
,
.
vidioc_s_tuner
=
vidioc_s_tuner
,
.
vidioc_g_audio
=
vidioc_g_audio
,
.
vidioc_s_audio
=
vidioc_s_audio
,
.
vidioc_g_input
=
vidioc_g_input
,
.
vidioc_s_input
=
vidioc_s_input
,
.
vidioc_g_frequency
=
vidioc_g_frequency
,
.
vidioc_s_frequency
=
vidioc_s_frequency
,
.
vidioc_queryctrl
=
vidioc_queryctrl
,
.
vidioc_g_ctrl
=
vidioc_g_ctrl
,
.
vidioc_s_ctrl
=
vidioc_s_ctrl
,
};
static
struct
video_device
tea575x_radio
=
{
.
name
=
"tea575x-tuner"
,
.
fops
=
&
tea575x_fops
,
.
ioctl_ops
=
&
tea575x_ioctl_ops
,
.
release
=
video_device_release
,
};
/*
* initialize all the tea575x chips
*/
void
snd_tea575x_init
(
struct
snd_tea575x
*
tea
)
{
int
retval
;
unsigned
int
val
;
struct
video_device
*
tea575x_radio_inst
;
val
=
tea
->
ops
->
read
(
tea
);
if
(
val
==
0x1ffffff
||
val
==
0
)
{
snd_printk
(
KERN_ERR
"Cannot find TEA575x chip
\n
"
);
snd_printk
(
KERN_ERR
"tea575x-tuner: Cannot find TEA575x chip
\n
"
);
return
;
}
memset
(
&
tea
->
vd
,
0
,
sizeof
(
tea
->
vd
));
strcpy
(
tea
->
vd
.
name
,
tea
->
tea5759
?
"TEA5759 radio"
:
"TEA5757 radio"
);
tea
->
vd
.
release
=
snd_tea575x_release
;
video_set_drvdata
(
&
tea
->
vd
,
tea
);
tea
->
vd
.
fops
=
&
tea
->
fops
;
tea
->
in_use
=
0
;
tea
->
fops
.
owner
=
tea
->
card
->
module
;
tea
->
f
ops
.
open
=
snd_tea575x_exclusive_open
;
tea
->
fops
.
release
=
snd_tea575x_exclusive_release
;
tea
->
fops
.
ioctl
=
snd_tea575x_ioctl
;
if
(
video_register_device
(
&
tea
->
vd
,
VFL_TYPE_RADIO
,
tea
->
dev_nr
-
1
)
<
0
)
{
snd_printk
(
KERN_ERR
"unable to register tea575x tuner
\n
"
);
tea
->
val
=
TEA575X_BIT_BAND_FM
|
TEA575X_BIT_SEARCH_10_40
;
tea
->
f
req
=
90500
*
16
;
/* 90.5Mhz default */
tea
575x_radio_inst
=
video_device_alloc
()
;
if
(
tea575x_radio_inst
==
NULL
)
{
printk
(
KERN_ERR
"tea575x-tuner: not enough memory
\n
"
);
return
;
}
tea
->
vd_registered
=
1
;
tea
->
val
=
TEA575X_BIT_BAND_FM
|
TEA575X_BIT_SEARCH_10_40
;
tea
->
freq
=
90500
*
16
;
/* 90.5Mhz default */
memcpy
(
tea575x_radio_inst
,
&
tea575x_radio
,
sizeof
(
tea575x_radio
));
strcpy
(
tea575x_radio
.
name
,
tea
->
tea5759
?
"TEA5759 radio"
:
"TEA5757 radio"
);
video_set_drvdata
(
tea575x_radio_inst
,
tea
);
retval
=
video_register_device
(
tea575x_radio_inst
,
VFL_TYPE_RADIO
,
radio_nr
);
if
(
retval
)
{
printk
(
KERN_ERR
"tea575x-tuner: can't register video device!
\n
"
);
kfree
(
tea575x_radio_inst
);
return
;
}
snd_tea575x_set_freq
(
tea
);
/* mute on init */
if
(
tea
->
ops
->
mute
)
if
(
tea
->
ops
->
mute
)
{
tea
->
ops
->
mute
(
tea
,
1
);
tea
->
mute
=
1
;
}
tea
->
vd
=
tea575x_radio_inst
;
}
void
snd_tea575x_exit
(
struct
snd_tea575x
*
tea
)
{
if
(
tea
->
vd
_registered
)
{
video_unregister_device
(
&
tea
->
vd
);
tea
->
vd
_registered
=
0
;
if
(
tea
->
vd
)
{
video_unregister_device
(
tea
->
vd
);
tea
->
vd
=
NULL
;
}
}
...
...
sound/pci/Kconfig
View file @
9b76ede4
...
...
@@ -507,7 +507,7 @@ config SND_FM801
config SND_FM801_TEA575X_BOOL
bool "ForteMedia FM801 + TEA5757 tuner"
depends on SND_FM801
depends on VIDEO_V4L
1=y || VIDEO_V4L1
=SND_FM801
depends on VIDEO_V4L
2=y || VIDEO_V4L2
=SND_FM801
help
Say Y here to include support for soundcards based on the ForteMedia
FM801 chip with a TEA5757 tuner connected to GPIO1-3 pins (Media
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment