Commit 007ad830 authored by Huang Shijie's avatar Huang Shijie Committed by Mauro Carvalho Chehab

V4L/DVB: tlg2300: remove the country code for analog tv and radio

video :
	use the V4L2_STD macros to select the proper audio setting.

radio :
	add preemphasis ctr.
	test it by the command:
	v4l2-ctl -d /dev/radio0 --set-ctrl=pre_emphasis_settings=1

[mchehab@redhat.com: folded documentation patch]
Signed-off-by: default avatarHuang Shijie <shijie8@gmail.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 5b3f03f0
......@@ -37,195 +37,11 @@ TESTED APPLICATIONS:
---------------------------------------------------------------------------
KNOWN PROBLEMS:
about preemphasis:
You can set the preemphasis for radio by the following command:
#v4l2-ctl -d /dev/radio0 --set-ctrl=pre_emphasis_settings=1
"pre_emphasis_settings=1" means that you select the 50us. If you want
to select the 75us, please use "pre_emphasis_settings=2"
country code
- The firmware of the chip needs the country code to determine
the stardards of video and audio when it runs for analog TV or radio.
The DVB-T does not need the country code.
So you must set the country-code correctly. The V4L2 does not have
the interface,the driver has to provide a parameter `country_code'.
You could set the coutry code in two ways, take USA as example
(The USA's country code is 1):
[1] add the following line in /etc/modprobe.conf before you insert the
card into USB hub's port :
poseidon country_code=1
[2] You can also modify the parameter at runtime (before you run the
application such as VLC)
#echo 1 > /sys/module/poseidon/parameter/country_code
The known country codes show below:
country code : country
93 "Afghanistan"
355 "Albania"
213 "Algeria"
684 "American Samoa"
376 "Andorra"
244 "Angola"
54 "Argentina"
374 "Armenia"
61 "Australia"
43 "Austria"
994 "Azerbaijan"
973 "Bahrain"
880 "Bangladesh"
375 "Belarus"
32 "Belgium"
501 "Belize"
229 "Benin"
591 "Bolivia"
387 "Bosnia and Herzegovina"
267 "Botswana"
55 "Brazil"
673 "Brunei Darussalam"
359 "Bulgalia"
226 "Burkina Faso"
257 "Burundi"
237 "Cameroon"
1 "Canada"
236 "Central African Republic"
235 "Chad"
56 "Chile"
86 "China"
57 "Colombia"
242 "Congo"
243 "Congo, Dem. Rep. of "
506 "Costa Rica"
385 "Croatia"
53 "Cuba or Guantanamo Bay"
357 "Cyprus"
420 "Czech Republic"
45 "Denmark"
246 "Diego Garcia"
253 "Djibouti"
593 "Ecuador"
20 "Egypt"
503 "El Salvador"
240 "Equatorial Guinea"
372 "Estonia"
251 "Ethiopia"
358 "Finland"
33 "France"
594 "French Guiana"
689 "French Polynesia"
241 "Gabonese Republic"
220 "Gambia"
995 "Georgia"
49 "Germany"
233 "Ghana"
350 "Gibraltar"
30 "Greece"
299 "Greenland"
671 "Guam"
502 "Guatemala"
592 "Guyana"
509 "Haiti"
504 "Honduras"
852 "Hong Kong SAR, China"
36 "Hungary"
354 "Iceland"
91 "India"
98 "Iran"
964 "Iraq"
353 "Ireland"
972 "Israel"
39 "Italy or Vatican City"
225 "Ivory Coast"
81 "Japan"
962 "Jordan"
7 "Kazakhstan or Kyrgyzstan"
254 "Kenya"
686 "Kiribati"
965 "Kuwait"
856 "Laos"
371 "Latvia"
961 "Lebanon"
266 "Lesotho"
231 "Liberia"
218 "Libya"
41 "Liechtenstein or Switzerland"
370 "Lithuania"
352 "Luxembourg"
853 "Macau SAR, China"
261 "Madagascar"
60 "Malaysia"
960 "Maldives"
223 "Mali Republic"
356 "Malta"
692 "Marshall Islands"
596 "Martinique"
222 "Mauritania"
230 "Mauritus"
52 "Mexico"
691 "Micronesia"
373 "Moldova"
377 "Monaco"
976 "Mongolia"
212 "Morocco"
258 "Mozambique"
95 "Myanmar"
264 "Namibia"
674 "Nauru"
31 "Netherlands"
687 "New Caledonia"
64 "New Zealand"
505 "Nicaragua"
227 "Niger"
234 "Nigeria"
850 "North Korea"
47 "Norway"
968 "Oman"
92 "Pakistan"
680 "Palau"
507 "Panama"
675 "Papua New Guinea"
595 "Paraguay"
51 "Peru"
63 "Philippines"
48 "Poland"
351 "Portugal"
974 "Qatar"
262 "Reunion Island"
40 "Romania"
7 "Russia"
378 "San Marino"
239 "Sao Tome and Principe"
966 "Saudi Arabia"
221 "Senegal"
248 "Seychelles Republic"
232 "Sierra Leone"
65 "Singapore"
421 "Slovak Republic"
386 "Slovenia"
27 "South Africa"
82 "South Korea "
34 "Spain"
94 "Sri Lanka"
508 "St. Pierre and Miquelon"
249 "Sudan"
597 "Suriname"
268 "Swaziland"
46 "Sweden"
963 "Syria"
886 "Taiwan Region"
255 "Tanzania"
66 "Thailand"
228 "Togolese Republic"
216 "Tunisia"
90 "Turkey"
993 "Turkmenistan"
256 "Uganda"
380 "Ukraine"
971 "United Arab Emirates"
44 "United Kingdom"
1 "United States of America"
598 "Uruguay"
58 "Venezuela"
84 "Vietnam"
967 "Yemen"
260 "Zambia"
255 "Zanzibar"
263 "Zimbabwe"
......@@ -118,6 +118,7 @@ struct radio_data {
__u32 fm_freq;
int users;
unsigned int is_radio_streaming;
int pre_emphasis;
struct video_device *fm_dev;
};
......@@ -185,7 +186,6 @@ struct poseidon {
struct pd_dvb_adapter dvb_data; /* DVB */
u32 state;
int country_code;
struct file *file_for_stream; /* the active stream*/
#ifdef CONFIG_PM
......@@ -240,7 +240,6 @@ struct video_device *vdev_init(struct poseidon *, struct video_device *);
int send_set_req(struct poseidon*, u8, s32, s32*);
int send_get_req(struct poseidon*, u8, s32, void*, s32*, s32);
s32 set_tuner_mode(struct poseidon*, unsigned char);
enum tlg__analog_audio_standard get_audio_std(s32, s32);
/* bulk urb alloc/free */
int alloc_bulk_urbs_generic(struct urb **urb_array, int num,
......@@ -252,7 +251,6 @@ void free_all_urb_generic(struct urb **urb_array, int num);
/* misc */
void poseidon_delete(struct kref *kref);
void destroy_video_device(struct video_device **v_dev);
extern int country_code;
extern int debug_mode;
void set_debug_mode(struct video_device *vfd, int debug_mode);
......
......@@ -189,41 +189,6 @@ int set_tuner_mode(struct poseidon *pd, unsigned char mode)
return 0;
}
enum tlg__analog_audio_standard get_audio_std(s32 mode, s32 country_code)
{
s32 nicam[] = {27, 32, 33, 34, 36, 44, 45, 46, 47, 48, 64,
65, 86, 351, 352, 353, 354, 358, 372, 852, 972};
s32 btsc[] = {1, 52, 54, 55, 886};
s32 eiaj[] = {81};
s32 i;
if (mode == TLG_MODE_FM_RADIO) {
if (country_code == 1)
return TLG_TUNE_ASTD_FM_US;
else
return TLG_TUNE_ASTD_FM_EUR;
} else if (mode == TLG_MODE_ANALOG_TV_UNCOMP) {
for (i = 0; i < sizeof(nicam) / sizeof(s32); i++) {
if (country_code == nicam[i])
return TLG_TUNE_ASTD_NICAM;
}
for (i = 0; i < sizeof(btsc) / sizeof(s32); i++) {
if (country_code == btsc[i])
return TLG_TUNE_ASTD_BTSC;
}
for (i = 0; i < sizeof(eiaj) / sizeof(s32); i++) {
if (country_code == eiaj[i])
return TLG_TUNE_ASTD_EIAJ;
}
return TLG_TUNE_ASTD_A2;
} else {
return TLG_TUNE_ASTD_NONE;
}
}
void poseidon_delete(struct kref *kref)
{
struct poseidon *pd = container_of(kref, struct poseidon, kref);
......@@ -462,7 +427,6 @@ static int poseidon_probe(struct usb_interface *interface,
struct device *dev = &interface->dev;
logpm(pd);
pd->country_code = 86;
mutex_init(&pd->lock);
/* register v4l2 device */
......
......@@ -22,9 +22,16 @@ static int poseidon_fm_open(struct file *filp);
#define TUNER_FREQ_MIN_FM 76000000
#define TUNER_FREQ_MAX_FM 108000000
#define MAX_PREEMPHASIS (V4L2_PREEMPHASIS_75_uS + 1)
static int preemphasis[MAX_PREEMPHASIS] = {
TLG_TUNE_ASTD_NONE, /* V4L2_PREEMPHASIS_DISABLED */
TLG_TUNE_ASTD_FM_EUR, /* V4L2_PREEMPHASIS_50_uS */
TLG_TUNE_ASTD_FM_US, /* V4L2_PREEMPHASIS_75_uS */
};
static int poseidon_check_mode_radio(struct poseidon *p)
{
int ret, radiomode;
int ret;
u32 status;
set_current_state(TASK_INTERRUPTIBLE);
......@@ -38,8 +45,8 @@ static int poseidon_check_mode_radio(struct poseidon *p)
goto out;
ret = send_set_req(p, SGNL_SRC_SEL, TLG_SIG_SRC_ANTENNA, &status);
radiomode = get_audio_std(TLG_MODE_FM_RADIO, p->country_code);
ret = send_set_req(p, TUNER_AUD_ANA_STD, radiomode, &status);
ret = send_set_req(p, TUNER_AUD_ANA_STD,
p->radio_data.pre_emphasis, &status);
ret |= send_set_req(p, TUNER_AUD_MODE,
TLG_TUNE_TVAUDIO_MODE_STEREO, &status);
ret |= send_set_req(p, AUDIO_SAMPLE_RATE_SEL,
......@@ -91,7 +98,9 @@ static int poseidon_fm_open(struct file *filp)
usb_autopm_get_interface(p->interface);
if (0 == p->state) {
p->country_code = country_code;
/* default pre-emphasis */
if (p->radio_data.pre_emphasis == 0)
p->radio_data.pre_emphasis = TLG_TUNE_ASTD_FM_EUR;
set_debug_mode(vfd, debug_mode);
ret = poseidon_check_mode_radio(p);
......@@ -205,13 +214,12 @@ int fm_get_freq(struct file *file, void *priv, struct v4l2_frequency *argp)
static int set_frequency(struct poseidon *p, __u32 frequency)
{
__u32 freq ;
int ret, status, radiomode;
int ret, status;
mutex_lock(&p->lock);
radiomode = get_audio_std(TLG_MODE_FM_RADIO, p->country_code);
/*NTSC 8,PAL 2 */
ret = send_set_req(p, TUNER_AUD_ANA_STD, radiomode, &status);
ret = send_set_req(p, TUNER_AUD_ANA_STD,
p->radio_data.pre_emphasis, &status);
freq = (frequency * 125) * 500 / 1000;/* kHZ */
if (freq < TUNER_FREQ_MIN_FM/1000 || freq > TUNER_FREQ_MAX_FM/1000) {
......@@ -253,27 +261,86 @@ int fm_set_freq(struct file *file, void *priv, struct v4l2_frequency *argp)
int tlg_fm_vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *arg)
{
return 0;
return 0;
}
int tlg_fm_vidioc_g_exts_ctrl(struct file *file, void *fh,
struct v4l2_ext_controls *ctrls)
{
struct poseidon *p = file->private_data;
int i;
if (ctrls->ctrl_class != V4L2_CTRL_CLASS_FM_TX)
return -EINVAL;
for (i = 0; i < ctrls->count; i++) {
struct v4l2_ext_control *ctrl = ctrls->controls + i;
if (ctrl->id != V4L2_CID_TUNE_PREEMPHASIS)
continue;
if (i < MAX_PREEMPHASIS)
ctrl->value = p->radio_data.pre_emphasis;
}
return 0;
}
int tlg_fm_vidioc_exts_ctrl(struct file *file, void *fh,
struct v4l2_ext_controls *a)
int tlg_fm_vidioc_s_exts_ctrl(struct file *file, void *fh,
struct v4l2_ext_controls *ctrls)
{
return 0;
int i;
if (ctrls->ctrl_class != V4L2_CTRL_CLASS_FM_TX)
return -EINVAL;
for (i = 0; i < ctrls->count; i++) {
struct v4l2_ext_control *ctrl = ctrls->controls + i;
if (ctrl->id != V4L2_CID_TUNE_PREEMPHASIS)
continue;
if (ctrl->value >= 0 && ctrl->value < MAX_PREEMPHASIS) {
struct poseidon *p = file->private_data;
int pre_emphasis = preemphasis[ctrl->value];
u32 status;
send_set_req(p, TUNER_AUD_ANA_STD,
pre_emphasis, &status);
p->radio_data.pre_emphasis = pre_emphasis;
}
}
return 0;
}
int tlg_fm_vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *arg)
struct v4l2_control *ctrl)
{
return 0;
return 0;
}
int tlg_fm_vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *arg)
struct v4l2_queryctrl *ctrl)
{
arg->minimum = 0;
arg->maximum = 65535;
return 0;
if (!(ctrl->id & V4L2_CTRL_FLAG_NEXT_CTRL))
return -EINVAL;
ctrl->id &= ~V4L2_CTRL_FLAG_NEXT_CTRL;
if (ctrl->id != V4L2_CID_TUNE_PREEMPHASIS) {
/* return the next supported control */
ctrl->id = V4L2_CID_TUNE_PREEMPHASIS;
v4l2_ctrl_query_fill(ctrl, V4L2_PREEMPHASIS_DISABLED,
V4L2_PREEMPHASIS_75_uS, 1,
V4L2_PREEMPHASIS_50_uS);
ctrl->flags = V4L2_CTRL_FLAG_UPDATE;
return 0;
}
return -EINVAL;
}
int tlg_fm_vidioc_querymenu(struct file *file, void *fh,
struct v4l2_querymenu *qmenu)
{
return v4l2_ctrl_query_menu(qmenu, NULL, NULL);
}
static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *vt)
......@@ -311,9 +378,11 @@ static const struct v4l2_ioctl_ops poseidon_fm_ioctl_ops = {
.vidioc_g_input = vidioc_g_input,
.vidioc_s_input = vidioc_s_input,
.vidioc_queryctrl = tlg_fm_vidioc_queryctrl,
.vidioc_querymenu = tlg_fm_vidioc_querymenu,
.vidioc_g_ctrl = tlg_fm_vidioc_g_ctrl,
.vidioc_s_ctrl = tlg_fm_vidioc_s_ctrl,
.vidioc_s_ext_ctrls = tlg_fm_vidioc_exts_ctrl,
.vidioc_s_ext_ctrls = tlg_fm_vidioc_s_exts_ctrl,
.vidioc_g_ext_ctrls = tlg_fm_vidioc_g_exts_ctrl,
.vidioc_s_tuner = vidioc_s_tuner,
.vidioc_g_tuner = tlg_fm_vidioc_g_tuner,
.vidioc_g_frequency = fm_get_freq,
......
......@@ -15,10 +15,6 @@ static int pm_video_suspend(struct poseidon *pd);
static int pm_video_resume(struct poseidon *pd);
static void iso_bubble_handler(struct work_struct *w);
int country_code = 86;
module_param(country_code, int, 0644);
MODULE_PARM_DESC(country_code, "country code (e.g China is 86)");
int usb_transfer_mode;
module_param(usb_transfer_mode, int, 0644);
MODULE_PARM_DESC(usb_transfer_mode, "0 = Bulk, 1 = Isochronous");
......@@ -93,27 +89,53 @@ static struct poseidon_control controls[] = {
{ V4L2_CID_BRIGHTNESS, V4L2_CTRL_TYPE_INTEGER,
"brightness", 0, 10000, 1, 100, 0, },
CUST_PARM_ID_BRIGHTNESS_CTRL
},
{
}, {
{ V4L2_CID_CONTRAST, V4L2_CTRL_TYPE_INTEGER,
"contrast", 0, 10000, 1, 100, 0, },
CUST_PARM_ID_CONTRAST_CTRL,
},
{
}, {
{ V4L2_CID_HUE, V4L2_CTRL_TYPE_INTEGER,
"hue", 0, 10000, 1, 100, 0, },
CUST_PARM_ID_HUE_CTRL,
},
{
}, {
{ V4L2_CID_SATURATION, V4L2_CTRL_TYPE_INTEGER,
"saturation", 0, 10000, 1, 100, 0, },
CUST_PARM_ID_SATURATION_CTRL,
},
};
struct video_std_to_audio_std {
v4l2_std_id video_std;
int audio_std;
};
static const struct video_std_to_audio_std video_to_audio_map[] = {
/* country : { 27, 32, 33, 34, 36, 44, 45, 46, 47, 48, 64,
65, 86, 351, 352, 353, 354, 358, 372, 852, 972 } */
{ (V4L2_STD_PAL_I | V4L2_STD_PAL_B | V4L2_STD_PAL_D |
V4L2_STD_SECAM_L | V4L2_STD_SECAM_D), TLG_TUNE_ASTD_NICAM },
/* country : { 1, 52, 54, 55, 886 } */
{V4L2_STD_NTSC_M | V4L2_STD_PAL_N | V4L2_STD_PAL_M, TLG_TUNE_ASTD_BTSC},
/* country : { 81 } */
{ V4L2_STD_NTSC_M_JP, TLG_TUNE_ASTD_EIAJ },
/* other country : TLG_TUNE_ASTD_A2 */
};
static const unsigned int map_size = ARRAY_SIZE(video_to_audio_map);
static int get_audio_std(v4l2_std_id v4l2_std)
{
int i = 0;
for (; i < map_size; i++) {
if (v4l2_std & video_to_audio_map[i].video_std)
return video_to_audio_map[i].audio_std;
}
return TLG_TUNE_ASTD_A2;
}
static int vidioc_querycap(struct file *file, void *fh,
struct v4l2_capability *cap)
{
......@@ -1067,7 +1089,7 @@ static int pd_vidioc_s_tuner(struct poseidon *pd, int index)
mutex_lock(&pd->lock);
param = pd_audio_modes[index].tlg_audio_mode;
ret = send_set_req(pd, TUNER_AUD_MODE, param, &cmd_status);
audiomode = get_audio_std(TLG_MODE_ANALOG_TV, pd->country_code);
audiomode = get_audio_std(pd->video_data.context.tvnormid);
ret |= send_set_req(pd, TUNER_AUD_ANA_STD, audiomode,
&cmd_status);
if (!ret)
......@@ -1255,9 +1277,7 @@ static int vidioc_streamoff(struct file *file, void *fh,
return videobuf_streamoff(&front->q);
}
/*
* Set the firmware' default values : need altersetting and country code
*/
/* Set the firmware's default values : need altersetting */
static int pd_video_checkmode(struct poseidon *pd)
{
s32 ret = 0, cmd_status, audiomode;
......@@ -1286,8 +1306,8 @@ static int pd_video_checkmode(struct poseidon *pd)
ret |= send_set_req(pd, TUNE_FREQ_SELECT, TUNER_FREQ_MIN, &cmd_status);
ret |= send_set_req(pd, VBI_DATA_SEL, 1, &cmd_status);/* enable vbi */
/* need country code to set the audio */
audiomode = get_audio_std(TLG_MODE_ANALOG_TV, pd->country_code);
/* set the audio */
audiomode = get_audio_std(pd->video_data.context.tvnormid);
ret |= send_set_req(pd, TUNER_AUD_ANA_STD, audiomode, &cmd_status);
ret |= send_set_req(pd, TUNER_AUD_MODE,
TLG_TUNE_TVAUDIO_MODE_STEREO, &cmd_status);
......@@ -1392,7 +1412,6 @@ static int pd_video_open(struct file *file)
goto out;
pd->cur_transfer_mode = usb_transfer_mode;/* bulk or iso */
pd->country_code = country_code;
init_video_context(&pd->video_data.context);
ret = pd_video_checkmode(pd);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment