21 #include <linux/kernel.h>
22 #include <linux/module.h>
27 #include <linux/slab.h>
36 #define PS3AV_BUF_SIZE 512
66 #define YUV444 PS3AV_CMD_VIDEO_CS_YUV444_8
67 #define RGB8 PS3AV_CMD_VIDEO_CS_RGB_8
69 #define XRGB PS3AV_CMD_VIDEO_FMT_X8R8G8B8
71 #define A_N PS3AV_CMD_AV_ASPECT_4_3
72 #define A_W PS3AV_CMD_AV_ASPECT_16_9
73 static const struct avset_video_mode {
80 } video_mode_table[] = {
98 static u32 cmd_table[] = {
142 #define PS3AV_EVENT_CMD_MASK 0x10000000
143 #define PS3AV_EVENT_ID_MASK 0x0000ffff
144 #define PS3AV_CID_MASK 0xffffffff
145 #define PS3AV_REPLY_BIT 0x80000000
147 #define ps3av_event_get_port_id(cid) ((cid >> 16) & 0xff)
155 for (i = 0;; table++, i++) {
156 if ((*table & mask) == (cid & mask))
172 "recv event packet cid:%08x port:0x%x size:%d\n",
177 "%s: failed event packet, cid:%08x size:%d\n",
178 __func__, hdr->
cid, hdr->
size);
185 #define POLLING_INTERVAL 25
188 const void *
buf,
unsigned long size)
191 dev_dbg(&dev->
core,
" -> %s:%d\n", __func__, __LINE__);
193 dev_dbg(&dev->
core,
" <- %s:%d\n", __func__, __LINE__);
194 return error ? error :
size;
198 unsigned long size,
int timeout)
203 dev_dbg(&dev->
core,
" -> %s:%d\n", __func__, __LINE__);
205 while (loopcnt++ <= timeout) {
219 static int ps3av_send_cmd_pkt(
const struct ps3av_send_hdr *send_buf,
231 res = ps3av_vuart_write(ps3av->dev, send_buf, write_len);
234 "%s: ps3av_vuart_write() failed (result=%d)\n",
247 "%s: ps3av_vuart_read() failed (result=%d)\n",
253 res = ps3av_vuart_read(ps3av->dev, &recv_buf->
cid,
254 recv_buf->
size, timeout);
257 "%s: ps3av_vuart_read() failed (result=%d)\n",
262 event = ps3av_parse_event_packet(recv_buf);
267 dev_dbg(&ps3av->dev->core,
"%s: reply err (result=%x)\n",
268 __func__, recv_buf->
cid);
282 dev_dbg(&ps3av->dev->core,
"reply_packet invalid version:%x\n",
287 if (return_len > user_buf_size)
288 return_len = user_buf_size;
289 memcpy(cmd_buf, recv_buf, return_len);
313 BUG_ON(usr_buf_size < send_len);
320 res = ps3av_send_cmd_pkt(buf, &ps3av->recv_buf.reply_hdr, send_len,
324 "%s: ps3av_send_cmd_pkt() failed (result=%d)\n",
330 res = ps3av_process_reply_packet(buf, &ps3av->recv_buf.reply_hdr,
343 printk(
KERN_ERR "%s: failed cid:%x res:%d\n", __func__, cid, res);
347 static int ps3av_set_av_video_mute(
u32 mute)
349 int i, num_of_av_port,
res;
351 num_of_av_port = ps3av->av_hw_conf.num_of_hdmi +
352 ps3av->av_hw_conf.num_of_avmulti;
354 for (i = 0; i < num_of_av_port; i++) {
363 static int ps3av_set_video_disable_sig(
void)
365 int i, num_of_hdmi_port, num_of_av_port,
res;
367 num_of_hdmi_port = ps3av->av_hw_conf.num_of_hdmi;
368 num_of_av_port = ps3av->av_hw_conf.num_of_hdmi +
369 ps3av->av_hw_conf.num_of_avmulti;
372 for (i = 0; i < num_of_hdmi_port; i++) {
381 for (i = 0; i < num_of_av_port; i++) {
385 if (i < num_of_hdmi_port) {
397 static int ps3av_set_audio_mute(
u32 mute)
399 int i, num_of_av_port, num_of_opt_port,
res;
401 num_of_av_port = ps3av->av_hw_conf.num_of_hdmi +
402 ps3av->av_hw_conf.num_of_avmulti;
403 num_of_opt_port = ps3av->av_hw_conf.num_of_spdif;
405 for (i = 0; i < num_of_av_port; i++) {
410 for (i = 0; i < num_of_opt_port; i++) {
426 num_of_audio = ps3av->av_hw_conf.num_of_hdmi +
427 ps3av->av_hw_conf.num_of_avmulti +
428 ps3av->av_hw_conf.num_of_spdif;
435 vid = video_mode_table[ps3av->ps3av_mode].vid;
444 "ps3av_cmd_audio_active OFF failed\n");
447 for (i = 0; i < num_of_audio; i++) {
449 fs, word_bits, format, source);
450 if (i < ps3av->av_hw_conf.num_of_hdmi) {
460 "ps3av_cmd_audio_mode failed, port:%x\n", i);
467 dev_dbg(&ps3av->dev->core,
"ps3av_cmd_avb_param failed\n");
476 "ps3av_cmd_audio_active ON failed\n");
482 static int ps3av_set_videomode(
void)
493 static void ps3av_set_videomode_packet(
u32 id)
504 avb_param.num_of_audio_pkt = 0;
505 avb_param.num_of_av_video_pkt = ps3av->av_hw_conf.num_of_hdmi +
506 ps3av->av_hw_conf.num_of_avmulti;
507 avb_param.num_of_av_audio_pkt = 0;
510 for (i = 0; i < avb_param.num_of_video_pkt; i++)
512 ps3av->head[i], video_mode->vid,
513 video_mode->fmt,
id);
515 for (i = 0; i < avb_param.num_of_av_video_pkt; i++) {
519 av_video_cs = video_mode->cs;
520 #ifndef PS3AV_HDMI_YUV
527 video_mode->vid, av_video_cs,
528 video_mode->aspect,
id);
535 "%s: Command failed. Please try your request again.\n",
538 dev_dbg(&ps3av->dev->core,
"ps3av_cmd_avb_param failed\n");
541 static void ps3av_set_videomode_cont(
u32 id,
u32 old_id)
547 ps3av_set_video_disable_sig();
563 dev_dbg(&ps3av->dev->core,
"Not supported\n");
566 "ps3av_cmd_av_hdmi_mode failed\n");
567 }
else if (old_id & PS3AV_MODE_HDCP_OFF) {
571 "ps3av_cmd_av_hdmi_mode failed\n");
574 ps3av_set_videomode_packet(
id);
583 ps3av_set_videomode_cont(ps3av->ps3av_mode, ps3av->ps3av_mode_old);
591 static const struct {
594 } ps3av_preferred_modes[] = {
631 for (i = 0; i <
ARRAY_SIZE(ps3av_preferred_modes); i++)
632 if (res_all & ps3av_preferred_modes[i].
mask)
633 return ps3av_preferred_modes[
i].id;
646 id = ps3av_resbit2id(info->
res_50.native, info->
res_60.native,
649 pr_debug(
"%s: Using native mode %d\n", __func__,
id);
654 id = ps3av_resbit2id(info->
res_50.res_bits, info->
res_60.res_bits,
657 pr_debug(
"%s: Using supported mode %d\n", __func__,
id);
665 pr_debug(
"%s: Using default mode %d\n", __func__,
id);
669 static void ps3av_monitor_info_dump(
680 for (i = 0; i <
sizeof(info->
monitor_id); i++)
688 pr_debug(
"resolution_60: bits: %08x native: %08x\n",
690 pr_debug(
"resolution_50: bits: %08x native: %08x\n",
692 pr_debug(
"resolution_other: bits: %08x native: %08x\n",
694 pr_debug(
"resolution_vesa: bits: %08x native: %08x\n",
698 pr_debug(
"color space rgb: %02x\n", info->
cs.rgb);
699 pr_debug(
"color space yuv444: %02x\n", info->
cs.yuv444);
700 pr_debug(
"color space yuv422: %02x\n", info->
cs.yuv422);
703 pr_debug(
"color info red: X %04x Y %04x\n", info->
color.red_x,
705 pr_debug(
"color info green: X %04x Y %04x\n", info->
color.green_x,
706 info->
color.green_y);
707 pr_debug(
"color info blue: X %04x Y %04x\n", info->
color.blue_x,
709 pr_debug(
"color info white: X %04x Y %04x\n", info->
color.white_x,
710 info->
color.white_y);
721 "audio[%d] type: %02x max_ch: %02x fs: %02x sbit: %02x\n",
728 static const struct ps3av_monitor_quirk {
731 } ps3av_monitor_quirks[] = {
733 .monitor_name =
"DELL 2007WFP",
736 .monitor_name =
"L226WTQ",
740 .monitor_name =
"SyncMaster",
748 const struct ps3av_monitor_quirk *quirk;
750 for (i = 0; i <
ARRAY_SIZE(ps3av_monitor_quirks); i++) {
751 quirk = &ps3av_monitor_quirks[
i];
754 pr_info(
"%s: Applying quirk for %s\n", __func__,
755 quirk->monitor_name);
756 info->
res_60.res_bits &= ~quirk->clear_60;
757 info->
res_60.native &= ~quirk->clear_60;
765 int i,
res,
id = 0, dvi = 0, rgb = 0;
777 ps3av_monitor_info_dump(&monitor_info);
779 info = &monitor_info.
info;
780 ps3av_fixup_monitor_info(info);
787 id = ps3av_hdmi_get_id(info);
800 pr_debug(
"%s: Using avmulti mode %d\n", __func__,
id);
803 return id | dvi | rgb;
806 static int ps3av_get_hw_conf(
struct ps3av *ps3av)
816 hw_conf = &ps3av->av_hw_conf;
848 if ((
id & PS3AV_MODE_MASK) > size - 1 ||
id < 0) {
849 dev_dbg(&ps3av->dev->core,
"%s: error id :%d\n", __func__,
id);
854 option =
id & ~PS3AV_MODE_MASK;
856 id = ps3av_auto_videomode(&ps3av->av_hw_conf);
866 ps3av->ps3av_mode_old = ps3av->ps3av_mode;
867 ps3av->ps3av_mode =
id;
868 if (ps3av_set_videomode())
869 ps3av->ps3av_mode = ps3av->ps3av_mode_old;
877 return ps3av_auto_videomode(&ps3av->av_hw_conf);
883 return ps3av ? ps3av->ps3av_mode : 0;
894 if (
id > size - 1 ||
id < 0) {
898 *xres = video_mode_table[
id].x;
899 *yres = video_mode_table[
id].y;
917 for (i = 0; i < ps3av->av_hw_conf.num_of_avmulti; i++) {
919 &ps3av->av_port[i + ps3av->av_hw_conf.num_of_hdmi],
940 dev_dbg(&dev->
core,
" -> %s:%d\n", __func__, __LINE__);
944 dev_err(&dev->
core,
"Only one ps3av device is supported\n");
957 init_completion(&ps3av->done);
987 ps3av_get_hw_conf(ps3av);
993 id = ps3av_auto_videomode(&ps3av->av_hw_conf);
1003 ps3av->ps3av_mode =
id;
1006 dev_dbg(&dev->
core,
" <- %s:%d\n", __func__, __LINE__);
1018 dev_dbg(&dev->
core,
" -> %s:%d\n", __func__, __LINE__);
1027 dev_dbg(&dev->
core,
" <- %s:%d\n", __func__, __LINE__);
1033 dev_dbg(&dev->
core,
" -> %s:%d\n", __func__, __LINE__);
1035 dev_dbg(&dev->
core,
" <- %s:%d\n", __func__, __LINE__);
1040 .core.core.name =
"ps3_av",
1041 .probe = ps3av_probe,
1042 .remove = ps3av_remove,
1043 .shutdown = ps3av_shutdown,
1046 static int __init ps3av_module_init(
void)
1050 if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
1053 pr_debug(
" -> %s:%d\n", __func__, __LINE__);
1058 "%s: ps3_vuart_port_driver_register failed %d\n",
1063 pr_debug(
" <- %s:%d\n", __func__, __LINE__);
1067 static void __exit ps3av_module_exit(
void)
1069 pr_debug(
" -> %s:%d\n", __func__, __LINE__);
1071 pr_debug(
" <- %s:%d\n", __func__, __LINE__);