Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
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
Hide 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
;
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 */
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
;
return
0
;
}
case
VIDIOCSTUNER
:
{
struct
video_tuner
v
;
if
(
copy_from_user
(
&
v
,
arg
,
sizeof
(
v
)))
return
-
EFAULT
;
if
(
v
.
tuner
!=
0
)
return
-
EINVAL
;
/* Only 1 tuner so no setting needed ! */
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
;
}
static
int
vidioc_g_tuner
(
struct
file
*
file
,
void
*
priv
,
struct
v4l2_tuner
*
v
)
{
if
(
v
->
index
>
0
)
return
-
EINVAL
;
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
;
}
static
int
vidioc_s_tuner
(
struct
file
*
file
,
void
*
priv
,
struct
v4l2_tuner
*
v
)
{
if
(
v
->
index
>
0
)
return
-
EINVAL
;
return
0
;
}
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
;
}
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
;
}
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
VIDIOCGFREQ
:
if
(
copy_to_user
(
arg
,
&
tea
->
freq
,
sizeof
(
tea
->
freq
)))
return
-
EFAULT
;
return
0
;
case
VIDIOCSFREQ
:
if
(
copy_from_user
(
&
tea
->
freq
,
arg
,
sizeof
(
tea
->
freq
)))
return
-
EFAULT
;
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
;
}
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
;
}
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
;
}
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
int
vidioc_g_input
(
struct
file
*
filp
,
void
*
priv
,
unsigned
int
*
i
)
{
*
i
=
0
;
return
0
;
}
static
void
snd_tea575x_release
(
struct
video_device
*
vfd
)
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