Lines Matching +full:playback +full:- +full:sd +full:- +full:lines
2 * saa717x - Philips SAA717xHL video decoder driver
7 * - Apply to SAA717x,NEC uPD64031,uPD64083. (1/31/2004)
9 * Changes by T.Adachi (tadachi@tadachi-net.com)
10 * - support audio, video scaler etc, and checked the initialize sequence.
36 #include <media/v4l2-device.h>
37 #include <media/v4l2-ctrls.h>
45 MODULE_PARM_DESC(debug, "Debug level (0-1)");
53 struct v4l2_subdev sd; member
59 int playback; member
72 static inline struct saa717x_state *to_state(struct v4l2_subdev *sd) in to_state() argument
74 return container_of(sd, struct saa717x_state, sd); in to_state()
79 return &container_of(ctrl->handler, struct saa717x_state, hdl)->sd; in to_sd()
82 /* ----------------------------------------------------------------------- */
93 /* ----------------------------------------------------------------------- */
95 static int saa717x_write(struct v4l2_subdev *sd, u32 reg, u32 value) in saa717x_write() argument
97 struct i2c_client *client = v4l2_get_subdevdata(sd); in saa717x_write()
98 struct i2c_adapter *adap = client->adapter; in saa717x_write()
104 msg.addr = client->addr; in saa717x_write()
117 v4l2_dbg(2, debug, sd, "wrote: reg 0x%03x=%08x\n", reg, value); in saa717x_write()
121 static void saa717x_write_regs(struct v4l2_subdev *sd, u32 *data) in saa717x_write_regs() argument
124 saa717x_write(sd, data[0], data[1]); in saa717x_write_regs()
129 static u32 saa717x_read(struct v4l2_subdev *sd, u32 reg) in saa717x_read() argument
131 struct i2c_client *client = v4l2_get_subdevdata(sd); in saa717x_read()
132 struct i2c_adapter *adap = client->adapter; in saa717x_read()
141 msgs[0].addr = msgs[1].addr = client->addr; in saa717x_read()
155 v4l2_dbg(2, debug, sd, "read: reg 0x%03x=0x%08x\n", reg, value); in saa717x_read()
159 /* ----------------------------------------------------------------------- */
231 0x010, 0x010, /* GREEN path gamma curve --- */
246 0x01f, 0x0ff, /* --- GREEN path gamma curve */
248 0x020, 0x010, /* BLUE path gamma curve --- */
263 0x02f, 0x0ff, /* --- BLUE path gamma curve */
265 0x030, 0x010, /* RED path gamma curve --- */
280 0x03f, 0x0ff, /* --- RED path gamma curve */
304 0x46c, 0xbbbb10, /* Digital output selection1-3 */
305 0x470, 0x101010, /* Digital output selection4-6 */
648 /* S-Video */
661 7-4: DMA2, 3-0: DMA1 ch. DMA4, DMA3 DMA2, DMA1
672 7-4:DAC right ch. 3-0:DAC left ch.
689 static void get_inf_dev_status(struct v4l2_subdev *sd, in get_inf_dev_status() argument
728 reg_data3 = saa717x_read(sd, 0x0528); in get_inf_dev_status()
730 v4l2_dbg(1, debug, sd, "tvaudio thread status: 0x%x [%s%s%s]\n", in get_inf_dev_status()
734 v4l2_dbg(1, debug, sd, "detailed status: " in get_inf_dev_status()
755 v4l2_dbg(1, debug, sd, "ST!!!\n"); in get_inf_dev_status()
760 v4l2_dbg(1, debug, sd, "DUAL!!!\n"); in get_inf_dev_status()
766 static void set_audio_mode(struct v4l2_subdev *sd, int audio_mode) in set_audio_mode() argument
768 v4l2_dbg(1, debug, sd, "writing registers to set audio mode by set %d\n", in set_audio_mode()
771 saa717x_write(sd, 0x46c, reg_set_audio_template[audio_mode][0]); in set_audio_mode()
772 saa717x_write(sd, 0x470, reg_set_audio_template[audio_mode][1]); in set_audio_mode()
776 static int set_audio_regs(struct v4l2_subdev *sd, in set_audio_regs() argument
779 u8 mute = 0xac; /* -84 dB */ in set_audio_regs()
784 saa717x_write(sd, 0x0594, decoder->audio_input); in set_audio_regs()
785 v4l2_dbg(1, debug, sd, "set audio input %d\n", in set_audio_regs()
786 decoder->audio_input); in set_audio_regs()
788 /* normalize ( 65535 to 0 -> 24 to -40 (not -84)) */ in set_audio_regs()
789 work_l = (min(65536 - decoder->audio_main_balance, 32768) * decoder->audio_main_volume) / 32768; in set_audio_regs()
790 work_r = (min(decoder->audio_main_balance, (u16)32768) * decoder->audio_main_volume) / 32768; in set_audio_regs()
791 decoder->audio_main_vol_l = (long)work_l * (24 - (-40)) / 65535 - 40; in set_audio_regs()
792 decoder->audio_main_vol_r = (long)work_r * (24 - (-40)) / 65535 - 40; in set_audio_regs()
795 /* main volume L[7-0],R[7-0],0x00 24=24dB,-83dB, -84(mute) */ in set_audio_regs()
796 /* def:0dB->6dB(MPG600GR) */ in set_audio_regs()
798 if (decoder->audio_main_mute) { in set_audio_regs()
801 val = (u8)decoder->audio_main_vol_l | in set_audio_regs()
802 ((u8)decoder->audio_main_vol_r << 8); in set_audio_regs()
805 saa717x_write(sd, 0x480, val); in set_audio_regs()
808 val = decoder->audio_main_bass & 0x1f; in set_audio_regs()
809 val |= (decoder->audio_main_treble & 0x1f) << 5; in set_audio_regs()
810 saa717x_write(sd, 0x488, val); in set_audio_regs()
815 static void set_h_prescale(struct v4l2_subdev *sd, in set_h_prescale() argument
848 saa717x_write(sd, 0x60 + task_shift, vals[i].xpsc); in set_h_prescale()
850 saa717x_write(sd, 0x61 + task_shift, vals[i].xacl); in set_h_prescale()
852 saa717x_write(sd, 0x62 + task_shift, in set_h_prescale()
855 saa717x_write(sd, 0x63 + task_shift, in set_h_prescale()
860 static void set_v_scale(struct v4l2_subdev *sd, int task, int yscale) in set_v_scale() argument
866 saa717x_write(sd, 0x70 + task_shift, yscale & 0xff); in set_v_scale()
868 saa717x_write(sd, 0x71 + task_shift, yscale >> 8); in set_v_scale()
873 struct v4l2_subdev *sd = to_sd(ctrl); in saa717x_s_ctrl() local
874 struct saa717x_state *state = to_state(sd); in saa717x_s_ctrl()
876 switch (ctrl->id) { in saa717x_s_ctrl()
878 saa717x_write(sd, 0x10a, ctrl->val); in saa717x_s_ctrl()
882 saa717x_write(sd, 0x10b, ctrl->val); in saa717x_s_ctrl()
886 saa717x_write(sd, 0x10c, ctrl->val); in saa717x_s_ctrl()
890 saa717x_write(sd, 0x10d, ctrl->val); in saa717x_s_ctrl()
894 state->audio_main_mute = ctrl->val; in saa717x_s_ctrl()
898 state->audio_main_volume = ctrl->val; in saa717x_s_ctrl()
902 state->audio_main_balance = ctrl->val; in saa717x_s_ctrl()
906 state->audio_main_treble = ctrl->val; in saa717x_s_ctrl()
910 state->audio_main_bass = ctrl->val; in saa717x_s_ctrl()
916 set_audio_regs(sd, state); in saa717x_s_ctrl()
920 static int saa717x_s_video_routing(struct v4l2_subdev *sd, in saa717x_s_video_routing() argument
923 struct saa717x_state *decoder = to_state(sd); in saa717x_s_video_routing()
928 v4l2_dbg(1, debug, sd, "decoder set input (%d)\n", input); in saa717x_s_video_routing()
929 /* inputs from 0-9 are available*/ in saa717x_s_video_routing()
930 /* saa717x have mode0-mode9 but mode5 is reserved. */ in saa717x_s_video_routing()
932 return -EINVAL; in saa717x_s_video_routing()
934 if (decoder->input != input) { in saa717x_s_video_routing()
937 decoder->input = input_line; in saa717x_s_video_routing()
938 v4l2_dbg(1, debug, sd, "now setting %s input %d\n", in saa717x_s_video_routing()
939 input_line >= 6 ? "S-Video" : "Composite", in saa717x_s_video_routing()
943 saa717x_write(sd, 0x102, in saa717x_s_video_routing()
944 (saa717x_read(sd, 0x102) & 0xf0) | in saa717x_s_video_routing()
948 saa717x_write(sd, 0x109, in saa717x_s_video_routing()
949 (saa717x_read(sd, 0x109) & 0x7f) | in saa717x_s_video_routing()
955 set_audio_mode(sd, decoder->tuner_audio_mode); in saa717x_s_video_routing()
958 * S-Video were chosen */ in saa717x_s_video_routing()
959 set_audio_mode(sd, TUNER_AUDIO_STEREO); in saa717x_s_video_routing()
961 /* change initialize procedure (Composite/S-Video) */ in saa717x_s_video_routing()
963 saa717x_write_regs(sd, reg_init_tuner_input); in saa717x_s_video_routing()
965 saa717x_write_regs(sd, reg_init_svideo_input); in saa717x_s_video_routing()
967 saa717x_write_regs(sd, reg_init_composite_input); in saa717x_s_video_routing()
974 static int saa717x_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) in saa717x_g_register() argument
976 reg->val = saa717x_read(sd, reg->reg); in saa717x_g_register()
977 reg->size = 1; in saa717x_g_register()
981 static int saa717x_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg) in saa717x_s_register() argument
983 u16 addr = reg->reg & 0xffff; in saa717x_s_register()
984 u8 val = reg->val & 0xff; in saa717x_s_register()
986 saa717x_write(sd, addr, val); in saa717x_s_register()
991 static int saa717x_set_fmt(struct v4l2_subdev *sd, in saa717x_set_fmt() argument
995 struct v4l2_mbus_framefmt *fmt = &format->format; in saa717x_set_fmt()
998 v4l2_dbg(1, debug, sd, "decoder set size\n"); in saa717x_set_fmt()
1000 if (format->pad || fmt->code != MEDIA_BUS_FMT_FIXED) in saa717x_set_fmt()
1001 return -EINVAL; in saa717x_set_fmt()
1004 if (fmt->width < 1 || fmt->width > 1440) in saa717x_set_fmt()
1005 return -EINVAL; in saa717x_set_fmt()
1006 if (fmt->height < 1 || fmt->height > 960) in saa717x_set_fmt()
1007 return -EINVAL; in saa717x_set_fmt()
1009 fmt->field = V4L2_FIELD_INTERLACED; in saa717x_set_fmt()
1010 fmt->colorspace = V4L2_COLORSPACE_SMPTE170M; in saa717x_set_fmt()
1012 if (format->which == V4L2_SUBDEV_FORMAT_TRY) in saa717x_set_fmt()
1017 prescale = SAA717X_NTSC_WIDTH / fmt->width; in saa717x_set_fmt()
1020 h_scale = 1024 * SAA717X_NTSC_WIDTH / prescale / fmt->width; in saa717x_set_fmt()
1022 v_scale = 512 * 2 * SAA717X_NTSC_HEIGHT / fmt->height; in saa717x_set_fmt()
1025 set_h_prescale(sd, 0, prescale); in saa717x_set_fmt()
1026 set_h_prescale(sd, 1, prescale); in saa717x_set_fmt()
1030 saa717x_write(sd, 0x6C, (u8)(h_scale & 0xFF)); in saa717x_set_fmt()
1031 saa717x_write(sd, 0x6D, (u8)((h_scale >> 8) & 0xFF)); in saa717x_set_fmt()
1033 saa717x_write(sd, 0xAC, (u8)(h_scale & 0xFF)); in saa717x_set_fmt()
1034 saa717x_write(sd, 0xAD, (u8)((h_scale >> 8) & 0xFF)); in saa717x_set_fmt()
1037 set_v_scale(sd, 0, v_scale); in saa717x_set_fmt()
1038 set_v_scale(sd, 1, v_scale); in saa717x_set_fmt()
1043 saa717x_write(sd, 0x5C, (u8)(fmt->width & 0xFF)); in saa717x_set_fmt()
1044 saa717x_write(sd, 0x5D, (u8)((fmt->width >> 8) & 0xFF)); in saa717x_set_fmt()
1046 saa717x_write(sd, 0x9C, (u8)(fmt->width & 0xFF)); in saa717x_set_fmt()
1047 saa717x_write(sd, 0x9D, (u8)((fmt->width >> 8) & 0xFF)); in saa717x_set_fmt()
1049 /* video number of lines at output */ in saa717x_set_fmt()
1051 saa717x_write(sd, 0x5E, (u8)(fmt->height & 0xFF)); in saa717x_set_fmt()
1052 saa717x_write(sd, 0x5F, (u8)((fmt->height >> 8) & 0xFF)); in saa717x_set_fmt()
1054 saa717x_write(sd, 0x9E, (u8)(fmt->height & 0xFF)); in saa717x_set_fmt()
1055 saa717x_write(sd, 0x9F, (u8)((fmt->height >> 8) & 0xFF)); in saa717x_set_fmt()
1059 static int saa717x_s_radio(struct v4l2_subdev *sd) in saa717x_s_radio() argument
1061 struct saa717x_state *decoder = to_state(sd); in saa717x_s_radio()
1063 decoder->radio = 1; in saa717x_s_radio()
1067 static int saa717x_s_std(struct v4l2_subdev *sd, v4l2_std_id std) in saa717x_s_std() argument
1069 struct saa717x_state *decoder = to_state(sd); in saa717x_s_std()
1071 v4l2_dbg(1, debug, sd, "decoder set norm "); in saa717x_s_std()
1072 v4l2_dbg(1, debug, sd, "(not yet implemented)\n"); in saa717x_s_std()
1074 decoder->radio = 0; in saa717x_s_std()
1075 decoder->std = std; in saa717x_s_std()
1079 static int saa717x_s_audio_routing(struct v4l2_subdev *sd, in saa717x_s_audio_routing() argument
1082 struct saa717x_state *decoder = to_state(sd); in saa717x_s_audio_routing()
1084 if (input < 3) { /* FIXME! --tadachi */ in saa717x_s_audio_routing()
1085 decoder->audio_input = input; in saa717x_s_audio_routing()
1086 v4l2_dbg(1, debug, sd, in saa717x_s_audio_routing()
1088 decoder->audio_input); in saa717x_s_audio_routing()
1089 set_audio_regs(sd, decoder); in saa717x_s_audio_routing()
1092 return -ERANGE; in saa717x_s_audio_routing()
1095 static int saa717x_s_stream(struct v4l2_subdev *sd, int enable) in saa717x_s_stream() argument
1097 struct saa717x_state *decoder = to_state(sd); in saa717x_s_stream()
1099 v4l2_dbg(1, debug, sd, "decoder %s output\n", in saa717x_s_stream()
1101 decoder->enable = enable; in saa717x_s_stream()
1102 saa717x_write(sd, 0x193, enable ? 0xa6 : 0x26); in saa717x_s_stream()
1107 static int saa717x_s_tuner(struct v4l2_subdev *sd, const struct v4l2_tuner *vt) in saa717x_s_tuner() argument
1109 struct saa717x_state *decoder = to_state(sd); in saa717x_s_tuner()
1117 switch (vt->audmode) { in saa717x_s_tuner()
1132 v4l2_dbg(1, debug, sd, "change audio mode to %s\n", in saa717x_s_tuner()
1134 decoder->tuner_audio_mode = audio_mode; in saa717x_s_tuner()
1137 set_audio_mode(sd, decoder->tuner_audio_mode); in saa717x_s_tuner()
1141 static int saa717x_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) in saa717x_g_tuner() argument
1143 struct saa717x_state *decoder = to_state(sd); in saa717x_g_tuner()
1146 if (decoder->radio) in saa717x_g_tuner()
1148 get_inf_dev_status(sd, &dual_f, &stereo_f); in saa717x_g_tuner()
1150 v4l2_dbg(1, debug, sd, "DETECT==st:%d dual:%d\n", in saa717x_g_tuner()
1155 vt->rxsubchans = V4L2_TUNER_SUB_MONO; in saa717x_g_tuner()
1156 v4l2_dbg(1, debug, sd, "DETECT==MONO\n"); in saa717x_g_tuner()
1161 if (vt->audmode == V4L2_TUNER_MODE_STEREO || in saa717x_g_tuner()
1162 vt->audmode == V4L2_TUNER_MODE_LANG1) { in saa717x_g_tuner()
1163 vt->rxsubchans = V4L2_TUNER_SUB_STEREO; in saa717x_g_tuner()
1164 v4l2_dbg(1, debug, sd, "DETECT==ST(ST)\n"); in saa717x_g_tuner()
1166 vt->rxsubchans = V4L2_TUNER_SUB_MONO; in saa717x_g_tuner()
1167 v4l2_dbg(1, debug, sd, "DETECT==ST(MONO)\n"); in saa717x_g_tuner()
1173 if (vt->audmode == V4L2_TUNER_MODE_LANG2) { in saa717x_g_tuner()
1174 vt->rxsubchans = V4L2_TUNER_SUB_LANG2 | V4L2_TUNER_SUB_MONO; in saa717x_g_tuner()
1175 v4l2_dbg(1, debug, sd, "DETECT==DUAL1\n"); in saa717x_g_tuner()
1177 vt->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_MONO; in saa717x_g_tuner()
1178 v4l2_dbg(1, debug, sd, "DETECT==DUAL2\n"); in saa717x_g_tuner()
1184 static int saa717x_log_status(struct v4l2_subdev *sd) in saa717x_log_status() argument
1186 struct saa717x_state *state = to_state(sd); in saa717x_log_status()
1188 v4l2_ctrl_handler_log_status(&state->hdl, sd->name); in saa717x_log_status()
1192 /* ----------------------------------------------------------------------- */
1234 /* ----------------------------------------------------------------------- */
1239 /* ----------------------------------------------------------------------- */
1245 struct v4l2_subdev *sd; in saa717x_probe() local
1250 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) in saa717x_probe()
1251 return -EIO; in saa717x_probe()
1253 decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL); in saa717x_probe()
1255 return -ENOMEM; in saa717x_probe()
1257 sd = &decoder->sd; in saa717x_probe()
1258 v4l2_i2c_subdev_init(sd, client, &saa717x_ops); in saa717x_probe()
1260 if (saa717x_write(sd, 0x5a4, 0xfe) && in saa717x_probe()
1261 saa717x_write(sd, 0x5a5, 0x0f) && in saa717x_probe()
1262 saa717x_write(sd, 0x5a6, 0x00) && in saa717x_probe()
1263 saa717x_write(sd, 0x5a7, 0x01)) in saa717x_probe()
1264 id = saa717x_read(sd, 0x5a0); in saa717x_probe()
1266 v4l2_dbg(1, debug, sd, "saa717x not found (id=%02x)\n", id); in saa717x_probe()
1267 return -ENODEV; in saa717x_probe()
1277 v4l2_info(sd, "%s found @ 0x%x (%s)\n", p, in saa717x_probe()
1278 client->addr << 1, client->adapter->name); in saa717x_probe()
1280 hdl = &decoder->hdl; in saa717x_probe()
1290 V4L2_CID_HUE, -128, 127, 1, 0); in saa717x_probe()
1296 V4L2_CID_AUDIO_BASS, -16, 15, 1, 0); in saa717x_probe()
1298 V4L2_CID_AUDIO_TREBLE, -16, 15, 1, 0); in saa717x_probe()
1301 sd->ctrl_handler = hdl; in saa717x_probe()
1302 if (hdl->error) { in saa717x_probe()
1303 int err = hdl->error; in saa717x_probe()
1309 decoder->std = V4L2_STD_NTSC; in saa717x_probe()
1310 decoder->input = -1; in saa717x_probe()
1311 decoder->enable = 1; in saa717x_probe()
1314 decoder->playback = 0; /* initially capture mode used */ in saa717x_probe()
1315 decoder->audio = 1; /* DECODER_AUDIO_48_KHZ */ in saa717x_probe()
1317 decoder->audio_input = 2; /* FIXME!! */ in saa717x_probe()
1319 decoder->tuner_audio_mode = TUNER_AUDIO_STEREO; in saa717x_probe()
1321 decoder->audio_main_vol_l = 6; in saa717x_probe()
1322 decoder->audio_main_vol_r = 6; in saa717x_probe()
1324 v4l2_dbg(1, debug, sd, "writing init values\n"); in saa717x_probe()
1327 saa717x_write_regs(sd, reg_init_initialize); in saa717x_probe()
1338 struct v4l2_subdev *sd = i2c_get_clientdata(client); in saa717x_remove() local
1340 v4l2_device_unregister_subdev(sd); in saa717x_remove()
1341 v4l2_ctrl_handler_free(sd->ctrl_handler); in saa717x_remove()
1345 /* ----------------------------------------------------------------------- */