Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] ps3: AV Settings Driver

Add the PS3 AV Settings Driver.

The AV Settings driver is used to control Audio and Video settings. It
communicates with the policy manager through the virtual uart.

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
Cc: James Simmons <jsimmons@infradead.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Geert Uytterhoeven and committed by
Linus Torvalds
11227fd1 5b8e8ee6

+2741
+11
arch/powerpc/platforms/ps3/Kconfig
··· 51 51 including the System Manager and AV Settings. In 52 52 general, all users will say Y. 53 53 54 + config PS3_PS3AV 55 + tristate "PS3 AV settings driver" 56 + depends on PPC_PS3 57 + select PS3_VUART 58 + default y 59 + help 60 + Include support for the PS3 AV Settings driver. 61 + 62 + This support is required for graphics and sound. In 63 + general, all users will say Y or M. 64 + 54 65 endmenu
+1
drivers/ps3/Makefile
··· 1 1 obj-$(CONFIG_PS3_VUART) += vuart.o 2 + obj-$(CONFIG_PS3_PS3AV) += ps3av.o ps3av_cmd.o
+974
drivers/ps3/ps3av.c
··· 1 + /* 2 + * Copyright (C) 2006 Sony Computer Entertainment Inc. 3 + * Copyright 2006, 2007 Sony Corporation 4 + * 5 + * AV backend support for PS3 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms of the GNU General Public License as published 9 + * by the Free Software Foundation; version 2 of the License. 10 + * 11 + * This program is distributed in the hope that it will be useful, but 12 + * WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 + * General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License along 17 + * with this program; if not, write to the Free Software Foundation, Inc., 18 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 + */ 20 + 21 + #include <linux/module.h> 22 + #include <linux/delay.h> 23 + #include <linux/notifier.h> 24 + #include <linux/reboot.h> 25 + #include <linux/kernel.h> 26 + #include <linux/ioctl.h> 27 + #include <asm/lv1call.h> 28 + #include <asm/ps3av.h> 29 + #include <asm/ps3.h> 30 + 31 + #include "vuart.h" 32 + 33 + #define BUFSIZE 4096 /* vuart buf size */ 34 + #define PS3AV_BUF_SIZE 512 /* max packet size */ 35 + 36 + static int timeout = 5000; /* in msec ( 5 sec ) */ 37 + module_param(timeout, int, 0644); 38 + 39 + static struct ps3av ps3av; 40 + 41 + static struct ps3_vuart_port_device ps3av_dev = { 42 + .match_id = PS3_MATCH_ID_AV_SETTINGS 43 + }; 44 + 45 + /* color space */ 46 + #define YUV444 PS3AV_CMD_VIDEO_CS_YUV444_8 47 + #define RGB8 PS3AV_CMD_VIDEO_CS_RGB_8 48 + /* format */ 49 + #define XRGB PS3AV_CMD_VIDEO_FMT_X8R8G8B8 50 + /* aspect */ 51 + #define A_N PS3AV_CMD_AV_ASPECT_4_3 52 + #define A_W PS3AV_CMD_AV_ASPECT_16_9 53 + static const struct avset_video_mode { 54 + u32 cs; 55 + u32 fmt; 56 + u32 vid; 57 + u32 aspect; 58 + u32 x; 59 + u32 y; 60 + u32 interlace; 61 + u32 freq; 62 + } video_mode_table[] = { 63 + { 0, }, /* auto */ 64 + {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_480I, A_N, 720, 480, 1, 60}, 65 + {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_480P, A_N, 720, 480, 0, 60}, 66 + {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_720P_60HZ, A_N, 1280, 720, 0, 60}, 67 + {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080I_60HZ, A_W, 1920, 1080, 1, 60}, 68 + {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080P_60HZ, A_W, 1920, 1080, 0, 60}, 69 + {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_576I, A_N, 720, 576, 1, 50}, 70 + {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_576P, A_N, 720, 576, 0, 50}, 71 + {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_720P_50HZ, A_N, 1280, 720, 0, 50}, 72 + {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080I_50HZ, A_W, 1920, 1080, 1, 50}, 73 + {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080P_50HZ, A_W, 1920, 1080, 0, 50}, 74 + { RGB8, XRGB, PS3AV_CMD_VIDEO_VID_WXGA, A_W, 1280, 768, 0, 60}, 75 + { RGB8, XRGB, PS3AV_CMD_VIDEO_VID_SXGA, A_N, 1280, 1024, 0, 60}, 76 + { RGB8, XRGB, PS3AV_CMD_VIDEO_VID_WUXGA, A_W, 1920, 1200, 0, 60}, 77 + }; 78 + 79 + /* supported CIDs */ 80 + static u32 cmd_table[] = { 81 + /* init */ 82 + PS3AV_CID_AV_INIT, 83 + PS3AV_CID_AV_FIN, 84 + PS3AV_CID_VIDEO_INIT, 85 + PS3AV_CID_AUDIO_INIT, 86 + 87 + /* set */ 88 + PS3AV_CID_AV_ENABLE_EVENT, 89 + PS3AV_CID_AV_DISABLE_EVENT, 90 + 91 + PS3AV_CID_AV_VIDEO_CS, 92 + PS3AV_CID_AV_VIDEO_MUTE, 93 + PS3AV_CID_AV_VIDEO_DISABLE_SIG, 94 + PS3AV_CID_AV_AUDIO_PARAM, 95 + PS3AV_CID_AV_AUDIO_MUTE, 96 + PS3AV_CID_AV_HDMI_MODE, 97 + PS3AV_CID_AV_TV_MUTE, 98 + 99 + PS3AV_CID_VIDEO_MODE, 100 + PS3AV_CID_VIDEO_FORMAT, 101 + PS3AV_CID_VIDEO_PITCH, 102 + 103 + PS3AV_CID_AUDIO_MODE, 104 + PS3AV_CID_AUDIO_MUTE, 105 + PS3AV_CID_AUDIO_ACTIVE, 106 + PS3AV_CID_AUDIO_INACTIVE, 107 + PS3AV_CID_AVB_PARAM, 108 + 109 + /* get */ 110 + PS3AV_CID_AV_GET_HW_CONF, 111 + PS3AV_CID_AV_GET_MONITOR_INFO, 112 + 113 + /* event */ 114 + PS3AV_CID_EVENT_UNPLUGGED, 115 + PS3AV_CID_EVENT_PLUGGED, 116 + PS3AV_CID_EVENT_HDCP_DONE, 117 + PS3AV_CID_EVENT_HDCP_FAIL, 118 + PS3AV_CID_EVENT_HDCP_AUTH, 119 + PS3AV_CID_EVENT_HDCP_ERROR, 120 + 121 + 0 122 + }; 123 + 124 + #define PS3AV_EVENT_CMD_MASK 0x10000000 125 + #define PS3AV_EVENT_ID_MASK 0x0000ffff 126 + #define PS3AV_CID_MASK 0xffffffff 127 + #define PS3AV_REPLY_BIT 0x80000000 128 + 129 + #define ps3av_event_get_port_id(cid) ((cid >> 16) & 0xff) 130 + 131 + static u32 *ps3av_search_cmd_table(u32 cid, u32 mask) 132 + { 133 + u32 *table; 134 + int i; 135 + 136 + table = cmd_table; 137 + for (i = 0;; table++, i++) { 138 + if ((*table & mask) == (cid & mask)) 139 + break; 140 + if (*table == 0) 141 + return NULL; 142 + } 143 + return table; 144 + } 145 + 146 + static int ps3av_parse_event_packet(const struct ps3av_reply_hdr *hdr) 147 + { 148 + u32 *table; 149 + 150 + if (hdr->cid & PS3AV_EVENT_CMD_MASK) { 151 + table = ps3av_search_cmd_table(hdr->cid, PS3AV_EVENT_CMD_MASK); 152 + if (table) 153 + dev_dbg(&ps3av_dev.core, 154 + "recv event packet cid:%08x port:0x%x size:%d\n", 155 + hdr->cid, ps3av_event_get_port_id(hdr->cid), 156 + hdr->size); 157 + else 158 + printk(KERN_ERR 159 + "%s: failed event packet, cid:%08x size:%d\n", 160 + __FUNCTION__, hdr->cid, hdr->size); 161 + return 1; /* receive event packet */ 162 + } 163 + return 0; 164 + } 165 + 166 + static int ps3av_send_cmd_pkt(const struct ps3av_send_hdr *send_buf, 167 + struct ps3av_reply_hdr *recv_buf, int write_len, 168 + int read_len) 169 + { 170 + int res; 171 + u32 cmd; 172 + int event; 173 + 174 + if (!ps3av.available) 175 + return -ENODEV; 176 + 177 + /* send pkt */ 178 + res = ps3av_vuart_write(ps3av.dev, send_buf, write_len); 179 + if (res < 0) { 180 + dev_dbg(&ps3av_dev.core, 181 + "%s: ps3av_vuart_write() failed (result=%d)\n", 182 + __FUNCTION__, res); 183 + return res; 184 + } 185 + 186 + /* recv pkt */ 187 + cmd = send_buf->cid; 188 + do { 189 + /* read header */ 190 + res = ps3av_vuart_read(ps3av.dev, recv_buf, PS3AV_HDR_SIZE, 191 + timeout); 192 + if (res != PS3AV_HDR_SIZE) { 193 + dev_dbg(&ps3av_dev.core, 194 + "%s: ps3av_vuart_read() failed (result=%d)\n", 195 + __FUNCTION__, res); 196 + return res; 197 + } 198 + 199 + /* read body */ 200 + res = ps3av_vuart_read(ps3av.dev, &recv_buf->cid, 201 + recv_buf->size, timeout); 202 + if (res < 0) { 203 + dev_dbg(&ps3av_dev.core, 204 + "%s: ps3av_vuart_read() failed (result=%d)\n", 205 + __FUNCTION__, res); 206 + return res; 207 + } 208 + res += PS3AV_HDR_SIZE; /* total len */ 209 + event = ps3av_parse_event_packet(recv_buf); 210 + /* ret > 0 event packet */ 211 + } while (event); 212 + 213 + if ((cmd | PS3AV_REPLY_BIT) != recv_buf->cid) { 214 + dev_dbg(&ps3av_dev.core, "%s: reply err (result=%x)\n", 215 + __FUNCTION__, recv_buf->cid); 216 + return -EINVAL; 217 + } 218 + 219 + return 0; 220 + } 221 + 222 + static int ps3av_process_reply_packet(struct ps3av_send_hdr *cmd_buf, 223 + const struct ps3av_reply_hdr *recv_buf, 224 + int user_buf_size) 225 + { 226 + int return_len; 227 + 228 + if (recv_buf->version != PS3AV_VERSION) { 229 + dev_dbg(&ps3av_dev.core, "reply_packet invalid version:%x\n", 230 + recv_buf->version); 231 + return -EFAULT; 232 + } 233 + return_len = recv_buf->size + PS3AV_HDR_SIZE; 234 + if (return_len > user_buf_size) 235 + return_len = user_buf_size; 236 + memcpy(cmd_buf, recv_buf, return_len); 237 + return 0; /* success */ 238 + } 239 + 240 + void ps3av_set_hdr(u32 cid, u16 size, struct ps3av_send_hdr *hdr) 241 + { 242 + hdr->version = PS3AV_VERSION; 243 + hdr->size = size - PS3AV_HDR_SIZE; 244 + hdr->cid = cid; 245 + } 246 + 247 + int ps3av_do_pkt(u32 cid, u16 send_len, size_t usr_buf_size, 248 + struct ps3av_send_hdr *buf) 249 + { 250 + int res = 0; 251 + union { 252 + struct ps3av_reply_hdr reply_hdr; 253 + u8 raw[PS3AV_BUF_SIZE]; 254 + } recv_buf; 255 + 256 + u32 *table; 257 + 258 + BUG_ON(!ps3av.available); 259 + 260 + if (down_interruptible(&ps3av.sem)) 261 + return -ERESTARTSYS; 262 + 263 + table = ps3av_search_cmd_table(cid, PS3AV_CID_MASK); 264 + BUG_ON(!table); 265 + BUG_ON(send_len < PS3AV_HDR_SIZE); 266 + BUG_ON(usr_buf_size < send_len); 267 + BUG_ON(usr_buf_size > PS3AV_BUF_SIZE); 268 + 269 + /* create header */ 270 + ps3av_set_hdr(cid, send_len, buf); 271 + 272 + /* send packet via vuart */ 273 + res = ps3av_send_cmd_pkt(buf, &recv_buf.reply_hdr, send_len, 274 + usr_buf_size); 275 + if (res < 0) { 276 + printk(KERN_ERR 277 + "%s: ps3av_send_cmd_pkt() failed (result=%d)\n", 278 + __FUNCTION__, res); 279 + goto err; 280 + } 281 + 282 + /* process reply packet */ 283 + res = ps3av_process_reply_packet(buf, &recv_buf.reply_hdr, 284 + usr_buf_size); 285 + if (res < 0) { 286 + printk(KERN_ERR "%s: put_return_status() failed (result=%d)\n", 287 + __FUNCTION__, res); 288 + goto err; 289 + } 290 + 291 + up(&ps3av.sem); 292 + return 0; 293 + 294 + err: 295 + up(&ps3av.sem); 296 + printk(KERN_ERR "%s: failed cid:%x res:%d\n", __FUNCTION__, cid, res); 297 + return res; 298 + } 299 + 300 + static int ps3av_set_av_video_mute(u32 mute) 301 + { 302 + int i, num_of_av_port, res; 303 + 304 + num_of_av_port = ps3av.av_hw_conf.num_of_hdmi + 305 + ps3av.av_hw_conf.num_of_avmulti; 306 + /* video mute on */ 307 + for (i = 0; i < num_of_av_port; i++) { 308 + res = ps3av_cmd_av_video_mute(1, &ps3av.av_port[i], mute); 309 + if (res < 0) 310 + return -1; 311 + } 312 + 313 + return 0; 314 + } 315 + 316 + static int ps3av_set_video_disable_sig(void) 317 + { 318 + int i, num_of_hdmi_port, num_of_av_port, res; 319 + 320 + num_of_hdmi_port = ps3av.av_hw_conf.num_of_hdmi; 321 + num_of_av_port = ps3av.av_hw_conf.num_of_hdmi + 322 + ps3av.av_hw_conf.num_of_avmulti; 323 + 324 + /* tv mute */ 325 + for (i = 0; i < num_of_hdmi_port; i++) { 326 + res = ps3av_cmd_av_tv_mute(ps3av.av_port[i], 327 + PS3AV_CMD_MUTE_ON); 328 + if (res < 0) 329 + return -1; 330 + } 331 + msleep(100); 332 + 333 + /* video mute on */ 334 + for (i = 0; i < num_of_av_port; i++) { 335 + res = ps3av_cmd_av_video_disable_sig(ps3av.av_port[i]); 336 + if (res < 0) 337 + return -1; 338 + if (i < num_of_hdmi_port) { 339 + res = ps3av_cmd_av_tv_mute(ps3av.av_port[i], 340 + PS3AV_CMD_MUTE_OFF); 341 + if (res < 0) 342 + return -1; 343 + } 344 + } 345 + msleep(300); 346 + 347 + return 0; 348 + } 349 + 350 + static int ps3av_set_audio_mute(u32 mute) 351 + { 352 + int i, num_of_av_port, num_of_opt_port, res; 353 + 354 + num_of_av_port = ps3av.av_hw_conf.num_of_hdmi + 355 + ps3av.av_hw_conf.num_of_avmulti; 356 + num_of_opt_port = ps3av.av_hw_conf.num_of_spdif; 357 + 358 + for (i = 0; i < num_of_av_port; i++) { 359 + res = ps3av_cmd_av_audio_mute(1, &ps3av.av_port[i], mute); 360 + if (res < 0) 361 + return -1; 362 + } 363 + for (i = 0; i < num_of_opt_port; i++) { 364 + res = ps3av_cmd_audio_mute(1, &ps3av.opt_port[i], mute); 365 + if (res < 0) 366 + return -1; 367 + } 368 + 369 + return 0; 370 + } 371 + 372 + int ps3av_set_audio_mode(u32 ch, u32 fs, u32 word_bits, u32 format, u32 source) 373 + { 374 + struct ps3av_pkt_avb_param avb_param; 375 + int i, num_of_audio, vid, res; 376 + struct ps3av_pkt_audio_mode audio_mode; 377 + u32 len = 0; 378 + 379 + num_of_audio = ps3av.av_hw_conf.num_of_hdmi + 380 + ps3av.av_hw_conf.num_of_avmulti + 381 + ps3av.av_hw_conf.num_of_spdif; 382 + 383 + avb_param.num_of_video_pkt = 0; 384 + avb_param.num_of_audio_pkt = PS3AV_AVB_NUM_AUDIO; /* always 0 */ 385 + avb_param.num_of_av_video_pkt = 0; 386 + avb_param.num_of_av_audio_pkt = ps3av.av_hw_conf.num_of_hdmi; 387 + 388 + vid = video_mode_table[ps3av.ps3av_mode].vid; 389 + 390 + /* audio mute */ 391 + ps3av_set_audio_mute(PS3AV_CMD_MUTE_ON); 392 + 393 + /* audio inactive */ 394 + res = ps3av_cmd_audio_active(0, ps3av.audio_port); 395 + if (res < 0) 396 + dev_dbg(&ps3av_dev.core, 397 + "ps3av_cmd_audio_active OFF failed\n"); 398 + 399 + /* audio_pkt */ 400 + for (i = 0; i < num_of_audio; i++) { 401 + ps3av_cmd_set_audio_mode(&audio_mode, ps3av.av_port[i], ch, fs, 402 + word_bits, format, source); 403 + if (i < ps3av.av_hw_conf.num_of_hdmi) { 404 + /* hdmi only */ 405 + len += ps3av_cmd_set_av_audio_param(&avb_param.buf[len], 406 + ps3av.av_port[i], 407 + &audio_mode, vid); 408 + } 409 + /* audio_mode pkt should be sent separately */ 410 + res = ps3av_cmd_audio_mode(&audio_mode); 411 + if (res < 0) 412 + dev_dbg(&ps3av_dev.core, 413 + "ps3av_cmd_audio_mode failed, port:%x\n", i); 414 + } 415 + 416 + /* send command using avb pkt */ 417 + len += offsetof(struct ps3av_pkt_avb_param, buf); 418 + res = ps3av_cmd_avb_param(&avb_param, len); 419 + if (res < 0) 420 + dev_dbg(&ps3av_dev.core, "ps3av_cmd_avb_param failed\n"); 421 + 422 + /* audio mute */ 423 + ps3av_set_audio_mute(PS3AV_CMD_MUTE_OFF); 424 + 425 + /* audio active */ 426 + res = ps3av_cmd_audio_active(1, ps3av.audio_port); 427 + if (res < 0) 428 + dev_dbg(&ps3av_dev.core, "ps3av_cmd_audio_active ON failed\n"); 429 + 430 + return 0; 431 + } 432 + 433 + EXPORT_SYMBOL_GPL(ps3av_set_audio_mode); 434 + 435 + static int ps3av_set_videomode(void) 436 + { 437 + /* av video mute */ 438 + ps3av_set_av_video_mute(PS3AV_CMD_MUTE_ON); 439 + 440 + /* wake up ps3avd to do the actual video mode setting */ 441 + up(&ps3av.ping); 442 + 443 + return 0; 444 + } 445 + 446 + static void ps3av_set_videomode_cont(u32 id, u32 old_id) 447 + { 448 + struct ps3av_pkt_avb_param avb_param; 449 + int i; 450 + u32 len = 0, av_video_cs; 451 + const struct avset_video_mode *video_mode; 452 + int res; 453 + 454 + video_mode = &video_mode_table[id & PS3AV_MODE_MASK]; 455 + 456 + avb_param.num_of_video_pkt = PS3AV_AVB_NUM_VIDEO; /* num of head */ 457 + avb_param.num_of_audio_pkt = 0; 458 + avb_param.num_of_av_video_pkt = ps3av.av_hw_conf.num_of_hdmi + 459 + ps3av.av_hw_conf.num_of_avmulti; 460 + avb_param.num_of_av_audio_pkt = 0; 461 + 462 + /* video signal off */ 463 + ps3av_set_video_disable_sig(); 464 + 465 + /* Retail PS3 product doesn't support this */ 466 + if (id & PS3AV_MODE_HDCP_OFF) { 467 + res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_HDCP_OFF); 468 + if (res == PS3AV_STATUS_UNSUPPORTED_HDMI_MODE) 469 + dev_dbg(&ps3av_dev.core, "Not supported\n"); 470 + else if (res) 471 + dev_dbg(&ps3av_dev.core, 472 + "ps3av_cmd_av_hdmi_mode failed\n"); 473 + } else if (old_id & PS3AV_MODE_HDCP_OFF) { 474 + res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_MODE_NORMAL); 475 + if (res < 0 && res != PS3AV_STATUS_UNSUPPORTED_HDMI_MODE) 476 + dev_dbg(&ps3av_dev.core, 477 + "ps3av_cmd_av_hdmi_mode failed\n"); 478 + } 479 + 480 + /* video_pkt */ 481 + for (i = 0; i < avb_param.num_of_video_pkt; i++) 482 + len += ps3av_cmd_set_video_mode(&avb_param.buf[len], 483 + ps3av.head[i], video_mode->vid, 484 + video_mode->fmt, id); 485 + /* av_video_pkt */ 486 + for (i = 0; i < avb_param.num_of_av_video_pkt; i++) { 487 + if (id & PS3AV_MODE_DVI || id & PS3AV_MODE_RGB) 488 + av_video_cs = RGB8; 489 + else 490 + av_video_cs = video_mode->cs; 491 + #ifndef PS3AV_HDMI_YUV 492 + if (ps3av.av_port[i] == PS3AV_CMD_AVPORT_HDMI_0 || 493 + ps3av.av_port[i] == PS3AV_CMD_AVPORT_HDMI_1) 494 + av_video_cs = RGB8; /* use RGB for HDMI */ 495 + #endif 496 + len += ps3av_cmd_set_av_video_cs(&avb_param.buf[len], 497 + ps3av.av_port[i], 498 + video_mode->vid, av_video_cs, 499 + video_mode->aspect, id); 500 + } 501 + /* send command using avb pkt */ 502 + len += offsetof(struct ps3av_pkt_avb_param, buf); 503 + res = ps3av_cmd_avb_param(&avb_param, len); 504 + if (res == PS3AV_STATUS_NO_SYNC_HEAD) 505 + printk(KERN_WARNING 506 + "%s: Command failed. Please try your request again. \n", 507 + __FUNCTION__); 508 + else if (res) 509 + dev_dbg(&ps3av_dev.core, "ps3av_cmd_avb_param failed\n"); 510 + 511 + msleep(1500); 512 + /* av video mute */ 513 + ps3av_set_av_video_mute(PS3AV_CMD_MUTE_OFF); 514 + } 515 + 516 + static int ps3avd(void *p) 517 + { 518 + struct ps3av *info = p; 519 + 520 + daemonize("ps3avd"); 521 + while (1) { 522 + down(&info->ping); 523 + ps3av_set_videomode_cont(info->ps3av_mode, 524 + info->ps3av_mode_old); 525 + up(&info->pong); 526 + } 527 + return 0; 528 + } 529 + 530 + static int ps3av_vid2table_id(int vid) 531 + { 532 + int i; 533 + 534 + for (i = 1; i < ARRAY_SIZE(video_mode_table); i++) 535 + if (video_mode_table[i].vid == vid) 536 + return i; 537 + return -1; 538 + } 539 + 540 + static int ps3av_resbit2vid(u32 res_50, u32 res_60) 541 + { 542 + int vid = -1; 543 + 544 + if (res_50 > res_60) { /* if res_50 == res_60, res_60 will be used */ 545 + if (res_50 & PS3AV_RESBIT_1920x1080P) 546 + vid = PS3AV_CMD_VIDEO_VID_1080P_50HZ; 547 + else if (res_50 & PS3AV_RESBIT_1920x1080I) 548 + vid = PS3AV_CMD_VIDEO_VID_1080I_50HZ; 549 + else if (res_50 & PS3AV_RESBIT_1280x720P) 550 + vid = PS3AV_CMD_VIDEO_VID_720P_50HZ; 551 + else if (res_50 & PS3AV_RESBIT_720x576P) 552 + vid = PS3AV_CMD_VIDEO_VID_576P; 553 + else 554 + vid = -1; 555 + } else { 556 + if (res_60 & PS3AV_RESBIT_1920x1080P) 557 + vid = PS3AV_CMD_VIDEO_VID_1080P_60HZ; 558 + else if (res_60 & PS3AV_RESBIT_1920x1080I) 559 + vid = PS3AV_CMD_VIDEO_VID_1080I_60HZ; 560 + else if (res_60 & PS3AV_RESBIT_1280x720P) 561 + vid = PS3AV_CMD_VIDEO_VID_720P_60HZ; 562 + else if (res_60 & PS3AV_RESBIT_720x480P) 563 + vid = PS3AV_CMD_VIDEO_VID_480P; 564 + else 565 + vid = -1; 566 + } 567 + return vid; 568 + } 569 + 570 + static int ps3av_hdmi_get_vid(struct ps3av_info_monitor *info) 571 + { 572 + u32 res_50, res_60; 573 + int vid = -1; 574 + 575 + if (info->monitor_type != PS3AV_MONITOR_TYPE_HDMI) 576 + return -1; 577 + 578 + /* check native resolution */ 579 + res_50 = info->res_50.native & PS3AV_RES_MASK_50; 580 + res_60 = info->res_60.native & PS3AV_RES_MASK_60; 581 + if (res_50 || res_60) { 582 + vid = ps3av_resbit2vid(res_50, res_60); 583 + return vid; 584 + } 585 + 586 + /* check resolution */ 587 + res_50 = info->res_50.res_bits & PS3AV_RES_MASK_50; 588 + res_60 = info->res_60.res_bits & PS3AV_RES_MASK_60; 589 + if (res_50 || res_60) { 590 + vid = ps3av_resbit2vid(res_50, res_60); 591 + return vid; 592 + } 593 + 594 + if (ps3av.region & PS3AV_REGION_60) 595 + vid = PS3AV_DEFAULT_HDMI_VID_REG_60; 596 + else 597 + vid = PS3AV_DEFAULT_HDMI_VID_REG_50; 598 + return vid; 599 + } 600 + 601 + static int ps3av_auto_videomode(struct ps3av_pkt_av_get_hw_conf *av_hw_conf, 602 + int boot) 603 + { 604 + int i, res, vid = -1, dvi = 0, rgb = 0; 605 + struct ps3av_pkt_av_get_monitor_info monitor_info; 606 + struct ps3av_info_monitor *info; 607 + 608 + /* get vid for hdmi */ 609 + for (i = 0; i < av_hw_conf->num_of_hdmi; i++) { 610 + res = ps3av_cmd_video_get_monitor_info(&monitor_info, 611 + PS3AV_CMD_AVPORT_HDMI_0 + 612 + i); 613 + if (res < 0) 614 + return -1; 615 + 616 + ps3av_cmd_av_monitor_info_dump(&monitor_info); 617 + info = &monitor_info.info; 618 + /* check DVI */ 619 + if (info->monitor_type == PS3AV_MONITOR_TYPE_DVI) { 620 + dvi = PS3AV_MODE_DVI; 621 + break; 622 + } 623 + /* check HDMI */ 624 + vid = ps3av_hdmi_get_vid(info); 625 + if (vid != -1) { 626 + /* got valid vid */ 627 + break; 628 + } 629 + } 630 + 631 + if (dvi) { 632 + /* DVI mode */ 633 + vid = PS3AV_DEFAULT_DVI_VID; 634 + } else if (vid == -1) { 635 + /* no HDMI interface or HDMI is off */ 636 + if (ps3av.region & PS3AV_REGION_60) 637 + vid = PS3AV_DEFAULT_AVMULTI_VID_REG_60; 638 + else 639 + vid = PS3AV_DEFAULT_AVMULTI_VID_REG_50; 640 + if (ps3av.region & PS3AV_REGION_RGB) 641 + rgb = PS3AV_MODE_RGB; 642 + } else if (boot) { 643 + /* HDMI: using DEFAULT HDMI_VID while booting up */ 644 + info = &monitor_info.info; 645 + if (ps3av.region & PS3AV_REGION_60) { 646 + if (info->res_60.res_bits & PS3AV_RESBIT_720x480P) 647 + vid = PS3AV_DEFAULT_HDMI_VID_REG_60; 648 + else if (info->res_50.res_bits & PS3AV_RESBIT_720x576P) 649 + vid = PS3AV_DEFAULT_HDMI_VID_REG_50; 650 + else { 651 + /* default */ 652 + vid = PS3AV_DEFAULT_HDMI_VID_REG_60; 653 + } 654 + } else { 655 + if (info->res_50.res_bits & PS3AV_RESBIT_720x576P) 656 + vid = PS3AV_DEFAULT_HDMI_VID_REG_50; 657 + else if (info->res_60.res_bits & PS3AV_RESBIT_720x480P) 658 + vid = PS3AV_DEFAULT_HDMI_VID_REG_60; 659 + else { 660 + /* default */ 661 + vid = PS3AV_DEFAULT_HDMI_VID_REG_50; 662 + } 663 + } 664 + } 665 + 666 + return (ps3av_vid2table_id(vid) | dvi | rgb); 667 + } 668 + 669 + static int ps3av_get_hw_conf(struct ps3av *ps3av) 670 + { 671 + int i, j, k, res; 672 + 673 + /* get av_hw_conf */ 674 + res = ps3av_cmd_av_get_hw_conf(&ps3av->av_hw_conf); 675 + if (res < 0) 676 + return -1; 677 + 678 + ps3av_cmd_av_hw_conf_dump(&ps3av->av_hw_conf); 679 + 680 + for (i = 0; i < PS3AV_HEAD_MAX; i++) 681 + ps3av->head[i] = PS3AV_CMD_VIDEO_HEAD_A + i; 682 + for (i = 0; i < PS3AV_OPT_PORT_MAX; i++) 683 + ps3av->opt_port[i] = PS3AV_CMD_AVPORT_SPDIF_0 + i; 684 + for (i = 0; i < ps3av->av_hw_conf.num_of_hdmi; i++) 685 + ps3av->av_port[i] = PS3AV_CMD_AVPORT_HDMI_0 + i; 686 + for (j = 0; j < ps3av->av_hw_conf.num_of_avmulti; j++) 687 + ps3av->av_port[i + j] = PS3AV_CMD_AVPORT_AVMULTI_0 + j; 688 + for (k = 0; k < ps3av->av_hw_conf.num_of_spdif; k++) 689 + ps3av->av_port[i + j + k] = PS3AV_CMD_AVPORT_SPDIF_0 + k; 690 + 691 + /* set all audio port */ 692 + ps3av->audio_port = PS3AV_CMD_AUDIO_PORT_HDMI_0 693 + | PS3AV_CMD_AUDIO_PORT_HDMI_1 694 + | PS3AV_CMD_AUDIO_PORT_AVMULTI_0 695 + | PS3AV_CMD_AUDIO_PORT_SPDIF_0 | PS3AV_CMD_AUDIO_PORT_SPDIF_1; 696 + 697 + return 0; 698 + } 699 + 700 + /* set mode using id */ 701 + int ps3av_set_video_mode(u32 id, int boot) 702 + { 703 + int size; 704 + u32 option; 705 + 706 + size = ARRAY_SIZE(video_mode_table); 707 + if ((id & PS3AV_MODE_MASK) > size - 1 || id < 0) { 708 + dev_dbg(&ps3av_dev.core, "%s: error id :%d\n", __FUNCTION__, 709 + id); 710 + return -EINVAL; 711 + } 712 + 713 + /* auto mode */ 714 + option = id & ~PS3AV_MODE_MASK; 715 + if ((id & PS3AV_MODE_MASK) == 0) { 716 + id = ps3av_auto_videomode(&ps3av.av_hw_conf, boot); 717 + if (id < 1) { 718 + printk(KERN_ERR "%s: invalid id :%d\n", __FUNCTION__, 719 + id); 720 + return -EINVAL; 721 + } 722 + id |= option; 723 + } 724 + 725 + /* set videomode */ 726 + down(&ps3av.pong); 727 + ps3av.ps3av_mode_old = ps3av.ps3av_mode; 728 + ps3av.ps3av_mode = id; 729 + if (ps3av_set_videomode()) 730 + ps3av.ps3av_mode = ps3av.ps3av_mode_old; 731 + 732 + return 0; 733 + } 734 + 735 + EXPORT_SYMBOL_GPL(ps3av_set_video_mode); 736 + 737 + int ps3av_set_mode(u32 id, int boot) 738 + { 739 + int res; 740 + 741 + res = ps3av_set_video_mode(id, boot); 742 + if (res) 743 + return res; 744 + 745 + res = ps3av_set_audio_mode(PS3AV_CMD_AUDIO_NUM_OF_CH_2, 746 + PS3AV_CMD_AUDIO_FS_48K, 747 + PS3AV_CMD_AUDIO_WORD_BITS_16, 748 + PS3AV_CMD_AUDIO_FORMAT_PCM, 749 + PS3AV_CMD_AUDIO_SOURCE_SERIAL); 750 + if (res) 751 + return res; 752 + 753 + return 0; 754 + } 755 + 756 + EXPORT_SYMBOL_GPL(ps3av_set_mode); 757 + 758 + int ps3av_get_mode(void) 759 + { 760 + return ps3av.ps3av_mode; 761 + } 762 + 763 + EXPORT_SYMBOL_GPL(ps3av_get_mode); 764 + 765 + int ps3av_get_scanmode(int id) 766 + { 767 + int size; 768 + 769 + id = id & PS3AV_MODE_MASK; 770 + size = ARRAY_SIZE(video_mode_table); 771 + if (id > size - 1 || id < 0) { 772 + printk(KERN_ERR "%s: invalid mode %d\n", __FUNCTION__, id); 773 + return -EINVAL; 774 + } 775 + return video_mode_table[id].interlace; 776 + } 777 + 778 + EXPORT_SYMBOL_GPL(ps3av_get_scanmode); 779 + 780 + int ps3av_get_refresh_rate(int id) 781 + { 782 + int size; 783 + 784 + id = id & PS3AV_MODE_MASK; 785 + size = ARRAY_SIZE(video_mode_table); 786 + if (id > size - 1 || id < 0) { 787 + printk(KERN_ERR "%s: invalid mode %d\n", __FUNCTION__, id); 788 + return -EINVAL; 789 + } 790 + return video_mode_table[id].freq; 791 + } 792 + 793 + EXPORT_SYMBOL_GPL(ps3av_get_refresh_rate); 794 + 795 + /* get resolution by video_mode */ 796 + int ps3av_video_mode2res(u32 id, u32 *xres, u32 *yres) 797 + { 798 + int size; 799 + 800 + id = id & PS3AV_MODE_MASK; 801 + size = ARRAY_SIZE(video_mode_table); 802 + if (id > size - 1 || id < 0) { 803 + printk(KERN_ERR "%s: invalid mode %d\n", __FUNCTION__, id); 804 + return -EINVAL; 805 + } 806 + *xres = video_mode_table[id].x; 807 + *yres = video_mode_table[id].y; 808 + return 0; 809 + } 810 + 811 + EXPORT_SYMBOL_GPL(ps3av_video_mode2res); 812 + 813 + /* mute */ 814 + int ps3av_video_mute(int mute) 815 + { 816 + return ps3av_set_av_video_mute(mute ? PS3AV_CMD_MUTE_ON 817 + : PS3AV_CMD_MUTE_OFF); 818 + } 819 + 820 + EXPORT_SYMBOL_GPL(ps3av_video_mute); 821 + 822 + int ps3av_audio_mute(int mute) 823 + { 824 + return ps3av_set_audio_mute(mute ? PS3AV_CMD_MUTE_ON 825 + : PS3AV_CMD_MUTE_OFF); 826 + } 827 + 828 + EXPORT_SYMBOL_GPL(ps3av_audio_mute); 829 + 830 + int ps3av_dev_open(void) 831 + { 832 + int status = 0; 833 + 834 + mutex_lock(&ps3av.mutex); 835 + if (!ps3av.open_count++) { 836 + status = lv1_gpu_open(0); 837 + if (status) { 838 + printk(KERN_ERR "%s: lv1_gpu_open failed %d\n", 839 + __FUNCTION__, status); 840 + ps3av.open_count--; 841 + } 842 + } 843 + mutex_unlock(&ps3av.mutex); 844 + 845 + return status; 846 + } 847 + 848 + EXPORT_SYMBOL_GPL(ps3av_dev_open); 849 + 850 + int ps3av_dev_close(void) 851 + { 852 + int status = 0; 853 + 854 + mutex_lock(&ps3av.mutex); 855 + if (ps3av.open_count <= 0) { 856 + printk(KERN_ERR "%s: GPU already closed\n", __FUNCTION__); 857 + status = -1; 858 + } else if (!--ps3av.open_count) { 859 + status = lv1_gpu_close(); 860 + if (status) 861 + printk(KERN_WARNING "%s: lv1_gpu_close failed %d\n", 862 + __FUNCTION__, status); 863 + } 864 + mutex_unlock(&ps3av.mutex); 865 + 866 + return status; 867 + } 868 + 869 + EXPORT_SYMBOL_GPL(ps3av_dev_close); 870 + 871 + static int ps3av_probe(struct ps3_vuart_port_device *dev) 872 + { 873 + int res; 874 + u32 id; 875 + 876 + dev_dbg(&ps3av_dev.core, "init ...\n"); 877 + dev_dbg(&ps3av_dev.core, " timeout=%d\n", timeout); 878 + 879 + memset(&ps3av, 0, sizeof(ps3av)); 880 + 881 + init_MUTEX(&ps3av.sem); 882 + init_MUTEX_LOCKED(&ps3av.ping); 883 + init_MUTEX(&ps3av.pong); 884 + mutex_init(&ps3av.mutex); 885 + ps3av.ps3av_mode = 0; 886 + ps3av.dev = dev; 887 + kernel_thread(ps3avd, &ps3av, CLONE_KERNEL); 888 + 889 + ps3av.available = 1; 890 + switch (ps3_os_area_get_av_multi_out()) { 891 + case PS3_PARAM_AV_MULTI_OUT_NTSC: 892 + ps3av.region = PS3AV_REGION_60; 893 + break; 894 + case PS3_PARAM_AV_MULTI_OUT_PAL_YCBCR: 895 + case PS3_PARAM_AV_MULTI_OUT_SECAM: 896 + ps3av.region = PS3AV_REGION_50; 897 + break; 898 + case PS3_PARAM_AV_MULTI_OUT_PAL_RGB: 899 + ps3av.region = PS3AV_REGION_50 | PS3AV_REGION_RGB; 900 + break; 901 + default: 902 + ps3av.region = PS3AV_REGION_60; 903 + break; 904 + } 905 + 906 + /* init avsetting modules */ 907 + res = ps3av_cmd_init(); 908 + if (res < 0) 909 + printk(KERN_ERR "%s: ps3av_cmd_init failed %d\n", __FUNCTION__, 910 + res); 911 + 912 + ps3av_get_hw_conf(&ps3av); 913 + id = ps3av_auto_videomode(&ps3av.av_hw_conf, 1); 914 + mutex_lock(&ps3av.mutex); 915 + ps3av.ps3av_mode = id; 916 + mutex_unlock(&ps3av.mutex); 917 + 918 + dev_dbg(&ps3av_dev.core, "init...done\n"); 919 + 920 + return 0; 921 + } 922 + 923 + static int ps3av_remove(struct ps3_vuart_port_device *dev) 924 + { 925 + if (ps3av.available) { 926 + ps3av_cmd_fin(); 927 + ps3av.available = 0; 928 + } 929 + 930 + return 0; 931 + } 932 + 933 + static void ps3av_shutdown(struct ps3_vuart_port_device *dev) 934 + { 935 + ps3av_remove(dev); 936 + } 937 + 938 + static struct ps3_vuart_port_driver ps3av_driver = { 939 + .match_id = PS3_MATCH_ID_AV_SETTINGS, 940 + .core = { 941 + .name = "ps3_av", 942 + }, 943 + .probe = ps3av_probe, 944 + .remove = ps3av_remove, 945 + .shutdown = ps3av_shutdown, 946 + }; 947 + 948 + static int ps3av_module_init(void) 949 + { 950 + int error = ps3_vuart_port_driver_register(&ps3av_driver); 951 + if (error) { 952 + printk(KERN_ERR 953 + "%s: ps3_vuart_port_driver_register failed %d\n", 954 + __FUNCTION__, error); 955 + return error; 956 + } 957 + 958 + error = ps3_vuart_port_device_register(&ps3av_dev); 959 + if (error) 960 + printk(KERN_ERR 961 + "%s: ps3_vuart_port_device_register failed %d\n", 962 + __FUNCTION__, error); 963 + 964 + return error; 965 + } 966 + 967 + static void __exit ps3av_module_exit(void) 968 + { 969 + device_unregister(&ps3av_dev.core); 970 + ps3_vuart_port_driver_unregister(&ps3av_driver); 971 + } 972 + 973 + subsys_initcall(ps3av_module_init); 974 + module_exit(ps3av_module_exit);
+1017
drivers/ps3/ps3av_cmd.c
··· 1 + /* 2 + * Copyright (C) 2006 Sony Computer Entertainment Inc. 3 + * Copyright 2006, 2007 Sony Corporation 4 + * 5 + * AV backend support for PS3 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms of the GNU General Public License as published 9 + * by the Free Software Foundation; version 2 of the License. 10 + * 11 + * This program is distributed in the hope that it will be useful, but 12 + * WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 + * General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License along 17 + * with this program; if not, write to the Free Software Foundation, Inc., 18 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 + */ 20 + 21 + #include <linux/module.h> 22 + #include <linux/kernel.h> 23 + #include <linux/delay.h> 24 + #include <asm/ps3av.h> 25 + #include <asm/ps3.h> 26 + 27 + #include "vuart.h" 28 + 29 + static const struct video_fmt { 30 + u32 format; 31 + u32 order; 32 + } ps3av_video_fmt_table[] = { 33 + { PS3AV_CMD_VIDEO_FORMAT_ARGB_8BIT, PS3AV_CMD_VIDEO_ORDER_RGB }, 34 + { PS3AV_CMD_VIDEO_FORMAT_ARGB_8BIT, PS3AV_CMD_VIDEO_ORDER_BGR }, 35 + }; 36 + 37 + static const struct { 38 + int cs; 39 + u32 av; 40 + u32 bl; 41 + } ps3av_cs_video2av_table[] = { 42 + { 43 + .cs = PS3AV_CMD_VIDEO_CS_RGB_8, 44 + .av = PS3AV_CMD_AV_CS_RGB_8, 45 + .bl = PS3AV_CMD_AV_CS_8 46 + }, { 47 + .cs = PS3AV_CMD_VIDEO_CS_RGB_10, 48 + .av = PS3AV_CMD_AV_CS_RGB_8, 49 + .bl = PS3AV_CMD_AV_CS_8 50 + }, { 51 + .cs = PS3AV_CMD_VIDEO_CS_RGB_12, 52 + .av = PS3AV_CMD_AV_CS_RGB_8, 53 + .bl = PS3AV_CMD_AV_CS_8 54 + }, { 55 + .cs = PS3AV_CMD_VIDEO_CS_YUV444_8, 56 + .av = PS3AV_CMD_AV_CS_YUV444_8, 57 + .bl = PS3AV_CMD_AV_CS_8 58 + }, { 59 + .cs = PS3AV_CMD_VIDEO_CS_YUV444_10, 60 + .av = PS3AV_CMD_AV_CS_YUV444_8, 61 + .bl = PS3AV_CMD_AV_CS_10 62 + }, { 63 + .cs = PS3AV_CMD_VIDEO_CS_YUV444_12, 64 + .av = PS3AV_CMD_AV_CS_YUV444_8, 65 + .bl = PS3AV_CMD_AV_CS_10 66 + }, { 67 + .cs = PS3AV_CMD_VIDEO_CS_YUV422_8, 68 + .av = PS3AV_CMD_AV_CS_YUV422_8, 69 + .bl = PS3AV_CMD_AV_CS_10 70 + }, { 71 + .cs = PS3AV_CMD_VIDEO_CS_YUV422_10, 72 + .av = PS3AV_CMD_AV_CS_YUV422_8, 73 + .bl = PS3AV_CMD_AV_CS_10 74 + }, { 75 + .cs = PS3AV_CMD_VIDEO_CS_YUV422_12, 76 + .av = PS3AV_CMD_AV_CS_YUV422_8, 77 + .bl = PS3AV_CMD_AV_CS_12 78 + }, { 79 + .cs = PS3AV_CMD_VIDEO_CS_XVYCC_8, 80 + .av = PS3AV_CMD_AV_CS_XVYCC_8, 81 + .bl = PS3AV_CMD_AV_CS_12 82 + }, { 83 + .cs = PS3AV_CMD_VIDEO_CS_XVYCC_10, 84 + .av = PS3AV_CMD_AV_CS_XVYCC_8, 85 + .bl = PS3AV_CMD_AV_CS_12 86 + }, { 87 + .cs = PS3AV_CMD_VIDEO_CS_XVYCC_12, 88 + .av = PS3AV_CMD_AV_CS_XVYCC_8, 89 + .bl = PS3AV_CMD_AV_CS_12 90 + } 91 + }; 92 + 93 + static u32 ps3av_cs_video2av(int cs) 94 + { 95 + unsigned int i; 96 + 97 + for (i = 0; i < ARRAY_SIZE(ps3av_cs_video2av_table); i++) 98 + if (ps3av_cs_video2av_table[i].cs == cs) 99 + return ps3av_cs_video2av_table[i].av; 100 + 101 + return PS3AV_CMD_AV_CS_RGB_8; 102 + } 103 + 104 + static u32 ps3av_cs_video2av_bitlen(int cs) 105 + { 106 + unsigned int i; 107 + 108 + for (i = 0; i < ARRAY_SIZE(ps3av_cs_video2av_table); i++) 109 + if (ps3av_cs_video2av_table[i].cs == cs) 110 + return ps3av_cs_video2av_table[i].bl; 111 + 112 + return PS3AV_CMD_AV_CS_8; 113 + } 114 + 115 + static const struct { 116 + int vid; 117 + u32 av; 118 + } ps3av_vid_video2av_table[] = { 119 + { PS3AV_CMD_VIDEO_VID_480I, PS3AV_CMD_AV_VID_480I }, 120 + { PS3AV_CMD_VIDEO_VID_480P, PS3AV_CMD_AV_VID_480P }, 121 + { PS3AV_CMD_VIDEO_VID_576I, PS3AV_CMD_AV_VID_576I }, 122 + { PS3AV_CMD_VIDEO_VID_576P, PS3AV_CMD_AV_VID_576P }, 123 + { PS3AV_CMD_VIDEO_VID_1080I_60HZ, PS3AV_CMD_AV_VID_1080I_60HZ }, 124 + { PS3AV_CMD_VIDEO_VID_720P_60HZ, PS3AV_CMD_AV_VID_720P_60HZ }, 125 + { PS3AV_CMD_VIDEO_VID_1080P_60HZ, PS3AV_CMD_AV_VID_1080P_60HZ }, 126 + { PS3AV_CMD_VIDEO_VID_1080I_50HZ, PS3AV_CMD_AV_VID_1080I_50HZ }, 127 + { PS3AV_CMD_VIDEO_VID_720P_50HZ, PS3AV_CMD_AV_VID_720P_50HZ }, 128 + { PS3AV_CMD_VIDEO_VID_1080P_50HZ, PS3AV_CMD_AV_VID_1080P_50HZ }, 129 + { PS3AV_CMD_VIDEO_VID_WXGA, PS3AV_CMD_AV_VID_WXGA }, 130 + { PS3AV_CMD_VIDEO_VID_SXGA, PS3AV_CMD_AV_VID_SXGA }, 131 + { PS3AV_CMD_VIDEO_VID_WUXGA, PS3AV_CMD_AV_VID_WUXGA } 132 + }; 133 + 134 + static u32 ps3av_vid_video2av(int vid) 135 + { 136 + unsigned int i; 137 + 138 + for (i = 0; i < ARRAY_SIZE(ps3av_vid_video2av_table); i++) 139 + if (ps3av_vid_video2av_table[i].vid == vid) 140 + return ps3av_vid_video2av_table[i].av; 141 + 142 + return PS3AV_CMD_AV_VID_480P; 143 + } 144 + 145 + int ps3av_cmd_init(void) 146 + { 147 + int res; 148 + struct ps3av_pkt_av_init av_init; 149 + struct ps3av_pkt_video_init video_init; 150 + struct ps3av_pkt_audio_init audio_init; 151 + 152 + /* video init */ 153 + memset(&video_init, 0, sizeof(video_init)); 154 + 155 + res = ps3av_do_pkt(PS3AV_CID_VIDEO_INIT, sizeof(video_init.send_hdr), 156 + sizeof(video_init), &video_init.send_hdr); 157 + if (res < 0) 158 + return res; 159 + 160 + res = get_status(&video_init); 161 + if (res) { 162 + printk(KERN_ERR "PS3AV_CID_VIDEO_INIT: failed %x\n", res); 163 + return res; 164 + } 165 + 166 + /* audio init */ 167 + memset(&audio_init, 0, sizeof(audio_init)); 168 + 169 + res = ps3av_do_pkt(PS3AV_CID_AUDIO_INIT, sizeof(audio_init.send_hdr), 170 + sizeof(audio_init), &audio_init.send_hdr); 171 + if (res < 0) 172 + return res; 173 + 174 + res = get_status(&audio_init); 175 + if (res) { 176 + printk(KERN_ERR "PS3AV_CID_AUDIO_INIT: failed %x\n", res); 177 + return res; 178 + } 179 + 180 + /* av init */ 181 + memset(&av_init, 0, sizeof(av_init)); 182 + av_init.event_bit = 0; 183 + 184 + res = ps3av_do_pkt(PS3AV_CID_AV_INIT, sizeof(av_init), sizeof(av_init), 185 + &av_init.send_hdr); 186 + if (res < 0) 187 + return res; 188 + 189 + res = get_status(&av_init); 190 + if (res) 191 + printk(KERN_ERR "PS3AV_CID_AV_INIT: failed %x\n", res); 192 + 193 + return res; 194 + } 195 + 196 + int ps3av_cmd_fin(void) 197 + { 198 + int res; 199 + struct ps3av_pkt_av_fin av_fin; 200 + 201 + memset(&av_fin, 0, sizeof(av_fin)); 202 + 203 + res = ps3av_do_pkt(PS3AV_CID_AV_FIN, sizeof(av_fin.send_hdr), 204 + sizeof(av_fin), &av_fin.send_hdr); 205 + if (res < 0) 206 + return res; 207 + 208 + res = get_status(&av_fin); 209 + if (res) 210 + printk(KERN_ERR "PS3AV_CID_AV_FIN: failed %x\n", res); 211 + 212 + return res; 213 + } 214 + 215 + int ps3av_cmd_av_video_mute(int num_of_port, u32 *port, u32 mute) 216 + { 217 + int i, send_len, res; 218 + struct ps3av_pkt_av_video_mute av_video_mute; 219 + 220 + if (num_of_port > PS3AV_MUTE_PORT_MAX) 221 + return -EINVAL; 222 + 223 + memset(&av_video_mute, 0, sizeof(av_video_mute)); 224 + for (i = 0; i < num_of_port; i++) { 225 + av_video_mute.mute[i].avport = port[i]; 226 + av_video_mute.mute[i].mute = mute; 227 + } 228 + 229 + send_len = sizeof(av_video_mute.send_hdr) + 230 + sizeof(struct ps3av_av_mute) * num_of_port; 231 + res = ps3av_do_pkt(PS3AV_CID_AV_VIDEO_MUTE, send_len, 232 + sizeof(av_video_mute), &av_video_mute.send_hdr); 233 + if (res < 0) 234 + return res; 235 + 236 + res = get_status(&av_video_mute); 237 + if (res) 238 + printk(KERN_ERR "PS3AV_CID_AV_VIDEO_MUTE: failed %x\n", res); 239 + 240 + return res; 241 + } 242 + 243 + int ps3av_cmd_av_video_disable_sig(u32 port) 244 + { 245 + int res; 246 + struct ps3av_pkt_av_video_disable_sig av_video_sig; 247 + 248 + memset(&av_video_sig, 0, sizeof(av_video_sig)); 249 + av_video_sig.avport = port; 250 + 251 + res = ps3av_do_pkt(PS3AV_CID_AV_VIDEO_DISABLE_SIG, 252 + sizeof(av_video_sig), sizeof(av_video_sig), 253 + &av_video_sig.send_hdr); 254 + if (res < 0) 255 + return res; 256 + 257 + res = get_status(&av_video_sig); 258 + if (res) 259 + printk(KERN_ERR 260 + "PS3AV_CID_AV_VIDEO_DISABLE_SIG: failed %x port:%x\n", 261 + res, port); 262 + 263 + return res; 264 + } 265 + 266 + int ps3av_cmd_av_tv_mute(u32 avport, u32 mute) 267 + { 268 + int res; 269 + struct ps3av_pkt_av_tv_mute tv_mute; 270 + 271 + memset(&tv_mute, 0, sizeof(tv_mute)); 272 + tv_mute.avport = avport; 273 + tv_mute.mute = mute; 274 + 275 + res = ps3av_do_pkt(PS3AV_CID_AV_TV_MUTE, sizeof(tv_mute), 276 + sizeof(tv_mute), &tv_mute.send_hdr); 277 + if (res < 0) 278 + return res; 279 + 280 + res = get_status(&tv_mute); 281 + if (res) 282 + printk(KERN_ERR "PS3AV_CID_AV_TV_MUTE: failed %x port:%x\n", 283 + res, avport); 284 + 285 + return res; 286 + } 287 + 288 + int ps3av_cmd_enable_event(void) 289 + { 290 + int res; 291 + struct ps3av_pkt_av_event av_event; 292 + 293 + memset(&av_event, 0, sizeof(av_event)); 294 + av_event.event_bit = PS3AV_CMD_EVENT_BIT_UNPLUGGED | 295 + PS3AV_CMD_EVENT_BIT_PLUGGED | PS3AV_CMD_EVENT_BIT_HDCP_DONE; 296 + 297 + res = ps3av_do_pkt(PS3AV_CID_AV_ENABLE_EVENT, sizeof(av_event), 298 + sizeof(av_event), &av_event.send_hdr); 299 + if (res < 0) 300 + return res; 301 + 302 + res = get_status(&av_event); 303 + if (res) 304 + printk(KERN_ERR "PS3AV_CID_AV_ENABLE_EVENT: failed %x\n", res); 305 + 306 + return res; 307 + } 308 + 309 + int ps3av_cmd_av_hdmi_mode(u8 mode) 310 + { 311 + int res; 312 + struct ps3av_pkt_av_hdmi_mode hdmi_mode; 313 + 314 + memset(&hdmi_mode, 0, sizeof(hdmi_mode)); 315 + hdmi_mode.mode = mode; 316 + 317 + res = ps3av_do_pkt(PS3AV_CID_AV_HDMI_MODE, sizeof(hdmi_mode), 318 + sizeof(hdmi_mode), &hdmi_mode.send_hdr); 319 + if (res < 0) 320 + return res; 321 + 322 + res = get_status(&hdmi_mode); 323 + if (res && res != PS3AV_STATUS_UNSUPPORTED_HDMI_MODE) 324 + printk(KERN_ERR "PS3AV_CID_AV_HDMI_MODE: failed %x\n", res); 325 + 326 + return res; 327 + } 328 + 329 + u32 ps3av_cmd_set_av_video_cs(void *p, u32 avport, int video_vid, int cs_out, 330 + int aspect, u32 id) 331 + { 332 + struct ps3av_pkt_av_video_cs *av_video_cs; 333 + 334 + av_video_cs = (struct ps3av_pkt_av_video_cs *)p; 335 + if (video_vid == -1) 336 + video_vid = PS3AV_CMD_VIDEO_VID_720P_60HZ; 337 + if (cs_out == -1) 338 + cs_out = PS3AV_CMD_VIDEO_CS_YUV444_8; 339 + if (aspect == -1) 340 + aspect = 0; 341 + 342 + memset(av_video_cs, 0, sizeof(*av_video_cs)); 343 + ps3av_set_hdr(PS3AV_CID_AV_VIDEO_CS, sizeof(*av_video_cs), 344 + &av_video_cs->send_hdr); 345 + av_video_cs->avport = avport; 346 + /* should be same as video_mode.resolution */ 347 + av_video_cs->av_vid = ps3av_vid_video2av(video_vid); 348 + av_video_cs->av_cs_out = ps3av_cs_video2av(cs_out); 349 + /* should be same as video_mode.video_cs_out */ 350 + av_video_cs->av_cs_in = ps3av_cs_video2av(PS3AV_CMD_VIDEO_CS_RGB_8); 351 + av_video_cs->bitlen_out = ps3av_cs_video2av_bitlen(cs_out); 352 + av_video_cs->aspect = aspect; 353 + if (id & PS3AV_MODE_DITHER) { 354 + av_video_cs->dither = PS3AV_CMD_AV_DITHER_ON 355 + | PS3AV_CMD_AV_DITHER_8BIT; 356 + } else { 357 + /* default off */ 358 + av_video_cs->dither = PS3AV_CMD_AV_DITHER_OFF; 359 + } 360 + 361 + return sizeof(*av_video_cs); 362 + } 363 + 364 + u32 ps3av_cmd_set_video_mode(void *p, u32 head, int video_vid, int video_fmt, 365 + u32 id) 366 + { 367 + struct ps3av_pkt_video_mode *video_mode; 368 + u32 x, y; 369 + 370 + video_mode = (struct ps3av_pkt_video_mode *)p; 371 + if (video_vid == -1) 372 + video_vid = PS3AV_CMD_VIDEO_VID_720P_60HZ; 373 + if (video_fmt == -1) 374 + video_fmt = PS3AV_CMD_VIDEO_FMT_X8R8G8B8; 375 + 376 + if (ps3av_video_mode2res(id, &x, &y)) 377 + return 0; 378 + 379 + /* video mode */ 380 + memset(video_mode, 0, sizeof(*video_mode)); 381 + ps3av_set_hdr(PS3AV_CID_VIDEO_MODE, sizeof(*video_mode), 382 + &video_mode->send_hdr); 383 + video_mode->video_head = head; 384 + if (video_vid == PS3AV_CMD_VIDEO_VID_480I 385 + && head == PS3AV_CMD_VIDEO_HEAD_B) 386 + video_mode->video_vid = PS3AV_CMD_VIDEO_VID_480I_A; 387 + else 388 + video_mode->video_vid = video_vid; 389 + video_mode->width = (u16) x; 390 + video_mode->height = (u16) y; 391 + video_mode->pitch = video_mode->width * 4; /* line_length */ 392 + video_mode->video_out_format = PS3AV_CMD_VIDEO_OUT_FORMAT_RGB_12BIT; 393 + video_mode->video_format = ps3av_video_fmt_table[video_fmt].format; 394 + video_mode->video_order = ps3av_video_fmt_table[video_fmt].order; 395 + 396 + pr_debug("%s: video_mode:vid:%x width:%d height:%d pitch:%d out_format:%d format:%x order:%x\n", 397 + __FUNCTION__, video_vid, video_mode->width, video_mode->height, 398 + video_mode->pitch, video_mode->video_out_format, 399 + video_mode->video_format, video_mode->video_order); 400 + return sizeof(*video_mode); 401 + } 402 + 403 + int ps3av_cmd_video_format_black(u32 head, u32 video_fmt, u32 mute) 404 + { 405 + int res; 406 + struct ps3av_pkt_video_format video_format; 407 + 408 + memset(&video_format, 0, sizeof(video_format)); 409 + video_format.video_head = head; 410 + if (mute != PS3AV_CMD_MUTE_OFF) 411 + video_format.video_format = PS3AV_CMD_VIDEO_FORMAT_BLACK; 412 + else 413 + video_format.video_format = 414 + ps3av_video_fmt_table[video_fmt].format; 415 + video_format.video_order = ps3av_video_fmt_table[video_fmt].order; 416 + 417 + res = ps3av_do_pkt(PS3AV_CID_VIDEO_FORMAT, sizeof(video_format), 418 + sizeof(video_format), &video_format.send_hdr); 419 + if (res < 0) 420 + return res; 421 + 422 + res = get_status(&video_format); 423 + if (res) 424 + printk(KERN_ERR "PS3AV_CID_VIDEO_FORMAT: failed %x\n", res); 425 + 426 + return res; 427 + } 428 + 429 + 430 + int ps3av_cmd_av_audio_mute(int num_of_port, u32 *port, u32 mute) 431 + { 432 + int i, res; 433 + struct ps3av_pkt_av_audio_mute av_audio_mute; 434 + 435 + if (num_of_port > PS3AV_MUTE_PORT_MAX) 436 + return -EINVAL; 437 + 438 + /* audio mute */ 439 + memset(&av_audio_mute, 0, sizeof(av_audio_mute)); 440 + for (i = 0; i < num_of_port; i++) { 441 + av_audio_mute.mute[i].avport = port[i]; 442 + av_audio_mute.mute[i].mute = mute; 443 + } 444 + 445 + res = ps3av_do_pkt(PS3AV_CID_AV_AUDIO_MUTE, 446 + sizeof(av_audio_mute.send_hdr) + 447 + sizeof(struct ps3av_av_mute) * num_of_port, 448 + sizeof(av_audio_mute), &av_audio_mute.send_hdr); 449 + if (res < 0) 450 + return res; 451 + 452 + res = get_status(&av_audio_mute); 453 + if (res) 454 + printk(KERN_ERR "PS3AV_CID_AV_AUDIO_MUTE: failed %x\n", res); 455 + 456 + return res; 457 + } 458 + 459 + static const struct { 460 + u32 fs; 461 + u8 mclk; 462 + } ps3av_cnv_mclk_table[] = { 463 + { PS3AV_CMD_AUDIO_FS_44K, PS3AV_CMD_AV_MCLK_512 }, 464 + { PS3AV_CMD_AUDIO_FS_48K, PS3AV_CMD_AV_MCLK_512 }, 465 + { PS3AV_CMD_AUDIO_FS_88K, PS3AV_CMD_AV_MCLK_256 }, 466 + { PS3AV_CMD_AUDIO_FS_96K, PS3AV_CMD_AV_MCLK_256 }, 467 + { PS3AV_CMD_AUDIO_FS_176K, PS3AV_CMD_AV_MCLK_128 }, 468 + { PS3AV_CMD_AUDIO_FS_192K, PS3AV_CMD_AV_MCLK_128 } 469 + }; 470 + 471 + static u8 ps3av_cnv_mclk(u32 fs) 472 + { 473 + unsigned int i; 474 + 475 + for (i = 0; i < ARRAY_SIZE(ps3av_cnv_mclk_table); i++) 476 + if (ps3av_cnv_mclk_table[i].fs == fs) 477 + return ps3av_cnv_mclk_table[i].mclk; 478 + 479 + printk(KERN_ERR "%s failed, fs:%x\n", __FUNCTION__, fs); 480 + return 0; 481 + } 482 + 483 + #define BASE PS3AV_CMD_AUDIO_FS_44K 484 + 485 + static const u32 ps3av_ns_table[][5] = { 486 + /* D1, D2, D3, D4, D5 */ 487 + [PS3AV_CMD_AUDIO_FS_44K-BASE] { 6272, 6272, 17836, 17836, 8918 }, 488 + [PS3AV_CMD_AUDIO_FS_48K-BASE] { 6144, 6144, 11648, 11648, 5824 }, 489 + [PS3AV_CMD_AUDIO_FS_88K-BASE] { 12544, 12544, 35672, 35672, 17836 }, 490 + [PS3AV_CMD_AUDIO_FS_96K-BASE] { 12288, 12288, 23296, 23296, 11648 }, 491 + [PS3AV_CMD_AUDIO_FS_176K-BASE] { 25088, 25088, 71344, 71344, 35672 }, 492 + [PS3AV_CMD_AUDIO_FS_192K-BASE] { 24576, 24576, 46592, 46592, 23296 } 493 + }; 494 + 495 + static void ps3av_cnv_ns(u8 *ns, u32 fs, u32 video_vid) 496 + { 497 + u32 av_vid, ns_val; 498 + u8 *p = ns; 499 + int d; 500 + 501 + d = ns_val = 0; 502 + av_vid = ps3av_vid_video2av(video_vid); 503 + switch (av_vid) { 504 + case PS3AV_CMD_AV_VID_480I: 505 + case PS3AV_CMD_AV_VID_576I: 506 + d = 0; 507 + break; 508 + case PS3AV_CMD_AV_VID_480P: 509 + case PS3AV_CMD_AV_VID_576P: 510 + d = 1; 511 + break; 512 + case PS3AV_CMD_AV_VID_1080I_60HZ: 513 + case PS3AV_CMD_AV_VID_1080I_50HZ: 514 + d = 2; 515 + break; 516 + case PS3AV_CMD_AV_VID_720P_60HZ: 517 + case PS3AV_CMD_AV_VID_720P_50HZ: 518 + d = 3; 519 + break; 520 + case PS3AV_CMD_AV_VID_1080P_60HZ: 521 + case PS3AV_CMD_AV_VID_1080P_50HZ: 522 + case PS3AV_CMD_AV_VID_WXGA: 523 + case PS3AV_CMD_AV_VID_SXGA: 524 + case PS3AV_CMD_AV_VID_WUXGA: 525 + d = 4; 526 + break; 527 + default: 528 + printk(KERN_ERR "%s failed, vid:%x\n", __FUNCTION__, 529 + video_vid); 530 + break; 531 + } 532 + 533 + if (fs < PS3AV_CMD_AUDIO_FS_44K || fs > PS3AV_CMD_AUDIO_FS_192K) 534 + printk(KERN_ERR "%s failed, fs:%x\n", __FUNCTION__, fs); 535 + else 536 + ns_val = ps3av_ns_table[PS3AV_CMD_AUDIO_FS_44K-BASE][d]; 537 + 538 + *p++ = ns_val & 0x000000FF; 539 + *p++ = (ns_val & 0x0000FF00) >> 8; 540 + *p = (ns_val & 0x00FF0000) >> 16; 541 + } 542 + 543 + #undef BASE 544 + 545 + static u8 ps3av_cnv_enable(u32 source, u8 *enable) 546 + { 547 + u8 *p, ret = 0; 548 + 549 + if (source == PS3AV_CMD_AUDIO_SOURCE_SPDIF) { 550 + ret = 0x03; 551 + } else if (source == PS3AV_CMD_AUDIO_SOURCE_SERIAL) { 552 + p = enable; 553 + ret = ((p[0] << 4) + (p[1] << 5) + (p[2] << 6) + (p[3] << 7)) | 554 + 0x01; 555 + } else 556 + printk(KERN_ERR "%s failed, source:%x\n", __FUNCTION__, 557 + source); 558 + return ret; 559 + } 560 + 561 + static u8 ps3av_cnv_fifomap(u8 *map) 562 + { 563 + u8 *p, ret = 0; 564 + 565 + p = map; 566 + ret = p[0] + (p[1] << 2) + (p[2] << 4) + (p[3] << 6); 567 + return ret; 568 + } 569 + 570 + static u8 ps3av_cnv_inputlen(u32 word_bits) 571 + { 572 + u8 ret = 0; 573 + 574 + switch (word_bits) { 575 + case PS3AV_CMD_AUDIO_WORD_BITS_16: 576 + ret = PS3AV_CMD_AV_INPUTLEN_16; 577 + break; 578 + case PS3AV_CMD_AUDIO_WORD_BITS_20: 579 + ret = PS3AV_CMD_AV_INPUTLEN_20; 580 + break; 581 + case PS3AV_CMD_AUDIO_WORD_BITS_24: 582 + ret = PS3AV_CMD_AV_INPUTLEN_24; 583 + break; 584 + default: 585 + printk(KERN_ERR "%s failed, word_bits:%x\n", __FUNCTION__, 586 + word_bits); 587 + break; 588 + } 589 + return ret; 590 + } 591 + 592 + static u8 ps3av_cnv_layout(u32 num_of_ch) 593 + { 594 + if (num_of_ch > PS3AV_CMD_AUDIO_NUM_OF_CH_8) { 595 + printk(KERN_ERR "%s failed, num_of_ch:%x\n", __FUNCTION__, 596 + num_of_ch); 597 + return 0; 598 + } 599 + 600 + return num_of_ch == PS3AV_CMD_AUDIO_NUM_OF_CH_2 ? 0x0 : 0x1; 601 + } 602 + 603 + static void ps3av_cnv_info(struct ps3av_audio_info_frame *info, 604 + const struct ps3av_pkt_audio_mode *mode) 605 + { 606 + info->pb1.cc = mode->audio_num_of_ch + 1; /* CH2:0x01 --- CH8:0x07 */ 607 + info->pb1.ct = 0; 608 + info->pb2.sf = 0; 609 + info->pb2.ss = 0; 610 + 611 + info->pb3 = 0; /* check mode->audio_format ?? */ 612 + info->pb4 = mode->audio_layout; 613 + info->pb5.dm = mode->audio_downmix; 614 + info->pb5.lsv = mode->audio_downmix_level; 615 + } 616 + 617 + static void ps3av_cnv_chstat(u8 *chstat, u8 *cs_info) 618 + { 619 + memcpy(chstat, cs_info, 5); 620 + } 621 + 622 + u32 ps3av_cmd_set_av_audio_param(void *p, u32 port, 623 + const struct ps3av_pkt_audio_mode *audio_mode, 624 + u32 video_vid) 625 + { 626 + struct ps3av_pkt_av_audio_param *param; 627 + 628 + param = (struct ps3av_pkt_av_audio_param *)p; 629 + 630 + memset(param, 0, sizeof(*param)); 631 + ps3av_set_hdr(PS3AV_CID_AV_AUDIO_PARAM, sizeof(*param), 632 + &param->send_hdr); 633 + 634 + param->avport = port; 635 + param->mclk = ps3av_cnv_mclk(audio_mode->audio_fs) | 0x80; 636 + ps3av_cnv_ns(param->ns, audio_mode->audio_fs, video_vid); 637 + param->enable = ps3av_cnv_enable(audio_mode->audio_source, 638 + audio_mode->audio_enable); 639 + param->swaplr = 0x09; 640 + param->fifomap = ps3av_cnv_fifomap(audio_mode->audio_map); 641 + param->inputctrl = 0x49; 642 + param->inputlen = ps3av_cnv_inputlen(audio_mode->audio_word_bits); 643 + param->layout = ps3av_cnv_layout(audio_mode->audio_num_of_ch); 644 + ps3av_cnv_info(&param->info, audio_mode); 645 + ps3av_cnv_chstat(param->chstat, audio_mode->audio_cs_info); 646 + 647 + return sizeof(*param); 648 + } 649 + 650 + /* default cs val */ 651 + static const u8 ps3av_mode_cs_info[] = { 652 + 0x00, 0x09, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00 653 + }; 654 + 655 + #define CS_44 0x00 656 + #define CS_48 0x02 657 + #define CS_88 0x08 658 + #define CS_96 0x0a 659 + #define CS_176 0x0c 660 + #define CS_192 0x0e 661 + #define CS_MASK 0x0f 662 + #define CS_BIT 0x40 663 + 664 + void ps3av_cmd_set_audio_mode(struct ps3av_pkt_audio_mode *audio, u32 avport, 665 + u32 ch, u32 fs, u32 word_bits, u32 format, 666 + u32 source) 667 + { 668 + int spdif_through, spdif_bitstream; 669 + int i; 670 + 671 + if (!(ch | fs | format | word_bits | source)) { 672 + ch = PS3AV_CMD_AUDIO_NUM_OF_CH_2; 673 + fs = PS3AV_CMD_AUDIO_FS_48K; 674 + word_bits = PS3AV_CMD_AUDIO_WORD_BITS_16; 675 + format = PS3AV_CMD_AUDIO_FORMAT_PCM; 676 + source = PS3AV_CMD_AUDIO_SOURCE_SERIAL; 677 + } 678 + spdif_through = spdif_bitstream = 0; /* XXX not supported */ 679 + 680 + /* audio mode */ 681 + memset(audio, 0, sizeof(*audio)); 682 + ps3av_set_hdr(PS3AV_CID_AUDIO_MODE, sizeof(*audio), &audio->send_hdr); 683 + 684 + audio->avport = (u8) avport; 685 + audio->mask = 0x0FFF; /* XXX set all */ 686 + audio->audio_num_of_ch = ch; 687 + audio->audio_fs = fs; 688 + audio->audio_word_bits = word_bits; 689 + audio->audio_format = format; 690 + audio->audio_source = source; 691 + 692 + switch (ch) { 693 + case PS3AV_CMD_AUDIO_NUM_OF_CH_8: 694 + audio->audio_enable[3] = 1; 695 + /* fall through */ 696 + case PS3AV_CMD_AUDIO_NUM_OF_CH_6: 697 + audio->audio_enable[2] = 1; 698 + audio->audio_enable[1] = 1; 699 + /* fall through */ 700 + case PS3AV_CMD_AUDIO_NUM_OF_CH_2: 701 + default: 702 + audio->audio_enable[0] = 1; 703 + } 704 + 705 + /* audio swap L/R */ 706 + for (i = 0; i < 4; i++) 707 + audio->audio_swap[i] = PS3AV_CMD_AUDIO_SWAP_0; /* no swap */ 708 + 709 + /* audio serial input mapping */ 710 + audio->audio_map[0] = PS3AV_CMD_AUDIO_MAP_OUTPUT_0; 711 + audio->audio_map[1] = PS3AV_CMD_AUDIO_MAP_OUTPUT_1; 712 + audio->audio_map[2] = PS3AV_CMD_AUDIO_MAP_OUTPUT_2; 713 + audio->audio_map[3] = PS3AV_CMD_AUDIO_MAP_OUTPUT_3; 714 + 715 + /* audio speaker layout */ 716 + if (avport == PS3AV_CMD_AVPORT_HDMI_0 || 717 + avport == PS3AV_CMD_AVPORT_HDMI_1) { 718 + switch (ch) { 719 + case PS3AV_CMD_AUDIO_NUM_OF_CH_8: 720 + audio->audio_layout = PS3AV_CMD_AUDIO_LAYOUT_8CH; 721 + break; 722 + case PS3AV_CMD_AUDIO_NUM_OF_CH_6: 723 + audio->audio_layout = PS3AV_CMD_AUDIO_LAYOUT_6CH; 724 + break; 725 + case PS3AV_CMD_AUDIO_NUM_OF_CH_2: 726 + default: 727 + audio->audio_layout = PS3AV_CMD_AUDIO_LAYOUT_2CH; 728 + break; 729 + } 730 + } else { 731 + audio->audio_layout = PS3AV_CMD_AUDIO_LAYOUT_2CH; 732 + } 733 + 734 + /* audio downmix permission */ 735 + audio->audio_downmix = PS3AV_CMD_AUDIO_DOWNMIX_PERMITTED; 736 + /* audio downmix level shift (0:0dB to 15:15dB) */ 737 + audio->audio_downmix_level = 0; /* 0dB */ 738 + 739 + /* set ch status */ 740 + for (i = 0; i < 8; i++) 741 + audio->audio_cs_info[i] = ps3av_mode_cs_info[i]; 742 + 743 + switch (fs) { 744 + case PS3AV_CMD_AUDIO_FS_44K: 745 + audio->audio_cs_info[3] &= ~CS_MASK; 746 + audio->audio_cs_info[3] |= CS_44; 747 + break; 748 + case PS3AV_CMD_AUDIO_FS_88K: 749 + audio->audio_cs_info[3] &= ~CS_MASK; 750 + audio->audio_cs_info[3] |= CS_88; 751 + break; 752 + case PS3AV_CMD_AUDIO_FS_96K: 753 + audio->audio_cs_info[3] &= ~CS_MASK; 754 + audio->audio_cs_info[3] |= CS_96; 755 + break; 756 + case PS3AV_CMD_AUDIO_FS_176K: 757 + audio->audio_cs_info[3] &= ~CS_MASK; 758 + audio->audio_cs_info[3] |= CS_176; 759 + break; 760 + case PS3AV_CMD_AUDIO_FS_192K: 761 + audio->audio_cs_info[3] &= ~CS_MASK; 762 + audio->audio_cs_info[3] |= CS_192; 763 + break; 764 + default: 765 + break; 766 + } 767 + 768 + /* pass through setting */ 769 + if (spdif_through && 770 + (avport == PS3AV_CMD_AVPORT_SPDIF_0 || 771 + avport == PS3AV_CMD_AVPORT_SPDIF_1)) { 772 + audio->audio_word_bits = PS3AV_CMD_AUDIO_WORD_BITS_16; 773 + audio->audio_source = PS3AV_CMD_AUDIO_SOURCE_SPDIF; 774 + if (spdif_bitstream) { 775 + audio->audio_format = PS3AV_CMD_AUDIO_FORMAT_BITSTREAM; 776 + audio->audio_cs_info[0] |= CS_BIT; 777 + } 778 + } 779 + } 780 + 781 + int ps3av_cmd_audio_mode(struct ps3av_pkt_audio_mode *audio_mode) 782 + { 783 + int res; 784 + 785 + res = ps3av_do_pkt(PS3AV_CID_AUDIO_MODE, sizeof(*audio_mode), 786 + sizeof(*audio_mode), &audio_mode->send_hdr); 787 + if (res < 0) 788 + return res; 789 + 790 + res = get_status(audio_mode); 791 + if (res) 792 + printk(KERN_ERR "PS3AV_CID_AUDIO_MODE: failed %x\n", res); 793 + 794 + return res; 795 + } 796 + 797 + int ps3av_cmd_audio_mute(int num_of_port, u32 *port, u32 mute) 798 + { 799 + int i, res; 800 + struct ps3av_pkt_audio_mute audio_mute; 801 + 802 + if (num_of_port > PS3AV_OPT_PORT_MAX) 803 + return -EINVAL; 804 + 805 + /* audio mute */ 806 + memset(&audio_mute, 0, sizeof(audio_mute)); 807 + for (i = 0; i < num_of_port; i++) { 808 + audio_mute.mute[i].avport = port[i]; 809 + audio_mute.mute[i].mute = mute; 810 + } 811 + 812 + res = ps3av_do_pkt(PS3AV_CID_AUDIO_MUTE, 813 + sizeof(audio_mute.send_hdr) + 814 + sizeof(struct ps3av_audio_mute) * num_of_port, 815 + sizeof(audio_mute), &audio_mute.send_hdr); 816 + if (res < 0) 817 + return res; 818 + 819 + res = get_status(&audio_mute); 820 + if (res) 821 + printk(KERN_ERR "PS3AV_CID_AUDIO_MUTE: failed %x\n", res); 822 + 823 + return res; 824 + } 825 + 826 + int ps3av_cmd_audio_active(int active, u32 port) 827 + { 828 + int res; 829 + struct ps3av_pkt_audio_active audio_active; 830 + u32 cid; 831 + 832 + /* audio active */ 833 + memset(&audio_active, 0, sizeof(audio_active)); 834 + audio_active.audio_port = port; 835 + cid = active ? PS3AV_CID_AUDIO_ACTIVE : PS3AV_CID_AUDIO_INACTIVE; 836 + 837 + res = ps3av_do_pkt(cid, sizeof(audio_active), sizeof(audio_active), 838 + &audio_active.send_hdr); 839 + if (res < 0) 840 + return res; 841 + 842 + res = get_status(&audio_active); 843 + if (res) 844 + printk(KERN_ERR "PS3AV_CID_AUDIO_ACTIVE:%x failed %x\n", cid, 845 + res); 846 + 847 + return res; 848 + } 849 + 850 + int ps3av_cmd_avb_param(struct ps3av_pkt_avb_param *avb, u32 send_len) 851 + { 852 + int res; 853 + 854 + /* avb packet */ 855 + 856 + res = ps3av_do_pkt(PS3AV_CID_AVB_PARAM, send_len, sizeof(*avb), 857 + &avb->send_hdr); 858 + if (res < 0) 859 + goto out; 860 + 861 + res = get_status(avb); 862 + if (res) 863 + pr_debug("%s: PS3AV_CID_AVB_PARAM: failed %x\n", __FUNCTION__, 864 + res); 865 + 866 + out: 867 + return res; 868 + } 869 + 870 + int ps3av_cmd_av_get_hw_conf(struct ps3av_pkt_av_get_hw_conf *hw_conf) 871 + { 872 + int res; 873 + 874 + memset(hw_conf, 0, sizeof(*hw_conf)); 875 + 876 + res = ps3av_do_pkt(PS3AV_CID_AV_GET_HW_CONF, sizeof(hw_conf->send_hdr), 877 + sizeof(*hw_conf), &hw_conf->send_hdr); 878 + if (res < 0) 879 + return res; 880 + 881 + res = get_status(hw_conf); 882 + if (res) 883 + printk(KERN_ERR "PS3AV_CID_AV_GET_HW_CONF: failed %x\n", res); 884 + 885 + return res; 886 + } 887 + 888 + int ps3av_cmd_video_get_monitor_info(struct ps3av_pkt_av_get_monitor_info *info, 889 + u32 avport) 890 + { 891 + int res; 892 + 893 + memset(info, 0, sizeof(*info)); 894 + info->avport = avport; 895 + 896 + res = ps3av_do_pkt(PS3AV_CID_AV_GET_MONITOR_INFO, 897 + sizeof(info->send_hdr) + sizeof(info->avport) + 898 + sizeof(info->reserved), 899 + sizeof(*info), &info->send_hdr); 900 + if (res < 0) 901 + return res; 902 + 903 + res = get_status(info); 904 + if (res) 905 + printk(KERN_ERR "PS3AV_CID_AV_GET_MONITOR_INFO: failed %x\n", 906 + res); 907 + 908 + return res; 909 + } 910 + 911 + #ifdef PS3AV_DEBUG 912 + void ps3av_cmd_av_hw_conf_dump(const struct ps3av_pkt_av_get_hw_conf *hw_conf) 913 + { 914 + printk("av_h_conf:num of hdmi:%d\n", hw_conf->num_of_hdmi); 915 + printk("av_h_conf:num of avmulti:%d\n", hw_conf->num_of_avmulti); 916 + printk("av_h_conf:num of spdif:%d\n", hw_conf->num_of_spdif); 917 + } 918 + 919 + void ps3av_cmd_av_monitor_info_dump(const struct ps3av_pkt_av_get_monitor_info *monitor_info) 920 + { 921 + const struct ps3av_info_monitor *info = &monitor_info->info; 922 + const struct ps3av_info_audio *audio = info->audio; 923 + int i; 924 + 925 + printk("Monitor Info: size%d\n", monitor_info->send_hdr.size); 926 + 927 + printk("avport:%02x\n", info->avport); 928 + printk("monitor_id:"); 929 + for (i = 0; i < 10; i++) 930 + printk("%02x ", info->monitor_id[i]); 931 + printk("\nmonitor_type:%02x\n", info->monitor_type); 932 + printk("monitor_name:"); 933 + for (i = 0; i < 16; i++) 934 + printk("%c", info->monitor_name[i]); 935 + 936 + /* resolution */ 937 + printk("\nresolution_60: bits:%08x native:%08x\n", 938 + info->res_60.res_bits, info->res_60.native); 939 + printk("resolution_50: bits:%08x native:%08x\n", 940 + info->res_50.res_bits, info->res_50.native); 941 + printk("resolution_other: bits:%08x native:%08x\n", 942 + info->res_other.res_bits, info->res_other.native); 943 + printk("resolution_vesa: bits:%08x native:%08x\n", 944 + info->res_vesa.res_bits, info->res_vesa.native); 945 + 946 + /* color space */ 947 + printk("color space rgb:%02x\n", info->cs.rgb); 948 + printk("color space yuv444:%02x\n", info->cs.yuv444); 949 + printk("color space yuv422:%02x\n", info->cs.yuv422); 950 + 951 + /* color info */ 952 + printk("color info red:X %04x Y %04x\n", 953 + info->color.red_x, info->color.red_y); 954 + printk("color info green:X %04x Y %04x\n", 955 + info->color.green_x, info->color.green_y); 956 + printk("color info blue:X %04x Y %04x\n", 957 + info->color.blue_x, info->color.blue_y); 958 + printk("color info white:X %04x Y %04x\n", 959 + info->color.white_x, info->color.white_y); 960 + printk("color info gamma: %08x\n", info->color.gamma); 961 + 962 + /* other info */ 963 + printk("supported_AI:%02x\n", info->supported_ai); 964 + printk("speaker_info:%02x\n", info->speaker_info); 965 + printk("num of audio:%02x\n", info->num_of_audio_block); 966 + 967 + /* audio block */ 968 + for (i = 0; i < info->num_of_audio_block; i++) { 969 + printk("audio[%d] type:%02x max_ch:%02x fs:%02x sbit:%02x\n", 970 + i, audio->type, audio->max_num_of_ch, audio->fs, 971 + audio->sbit); 972 + audio++; 973 + } 974 + } 975 + #endif /* PS3AV_DEBUG */ 976 + 977 + #define PS3AV_AV_LAYOUT_0 (PS3AV_CMD_AV_LAYOUT_32 \ 978 + | PS3AV_CMD_AV_LAYOUT_44 \ 979 + | PS3AV_CMD_AV_LAYOUT_48) 980 + 981 + #define PS3AV_AV_LAYOUT_1 (PS3AV_AV_LAYOUT_0 \ 982 + | PS3AV_CMD_AV_LAYOUT_88 \ 983 + | PS3AV_CMD_AV_LAYOUT_96 \ 984 + | PS3AV_CMD_AV_LAYOUT_176 \ 985 + | PS3AV_CMD_AV_LAYOUT_192) 986 + 987 + /************************* vuart ***************************/ 988 + 989 + #define POLLING_INTERVAL 25 /* in msec */ 990 + 991 + int ps3av_vuart_write(struct ps3_vuart_port_device *dev, const void *buf, 992 + unsigned long size) 993 + { 994 + int error = ps3_vuart_write(dev, buf, size); 995 + return error ? error : size; 996 + } 997 + 998 + int ps3av_vuart_read(struct ps3_vuart_port_device *dev, void *buf, 999 + unsigned long size, int timeout) 1000 + { 1001 + int error; 1002 + int loopcnt = 0; 1003 + 1004 + timeout = (timeout + POLLING_INTERVAL - 1) / POLLING_INTERVAL; 1005 + while (loopcnt++ <= timeout) { 1006 + error = ps3_vuart_read(dev, buf, size); 1007 + if (!error) 1008 + return size; 1009 + if (error != -EAGAIN) { 1010 + printk(KERN_ERR "%s: ps3_vuart_read failed %d\n", 1011 + __FUNCTION__, error); 1012 + return error; 1013 + } 1014 + msleep(POLLING_INTERVAL); 1015 + } 1016 + return -EWOULDBLOCK; 1017 + }
+738
include/asm-powerpc/ps3av.h
··· 1 + /* 2 + * Copyright (C) 2006 Sony Computer Entertainment Inc. 3 + * Copyright 2006, 2007 Sony Corporation 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms of the GNU General Public License as published 7 + * by the Free Software Foundation; version 2 of the License. 8 + * 9 + * This program is distributed in the hope that it will be useful, but 10 + * WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 + * General Public License for more details. 13 + * 14 + * You should have received a copy of the GNU General Public License along 15 + * with this program; if not, write to the Free Software Foundation, Inc., 16 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 + */ 18 + #ifndef _ASM_POWERPC_PS3AV_H_ 19 + #define _ASM_POWERPC_PS3AV_H_ 20 + 21 + #include <linux/mutex.h> 22 + 23 + /** command for ioctl() **/ 24 + #define PS3AV_VERSION 0x205 /* version of ps3av command */ 25 + 26 + #define PS3AV_CID_AV_INIT 0x00000001 27 + #define PS3AV_CID_AV_FIN 0x00000002 28 + #define PS3AV_CID_AV_GET_HW_CONF 0x00000003 29 + #define PS3AV_CID_AV_GET_MONITOR_INFO 0x00000004 30 + #define PS3AV_CID_AV_ENABLE_EVENT 0x00000006 31 + #define PS3AV_CID_AV_DISABLE_EVENT 0x00000007 32 + #define PS3AV_CID_AV_TV_MUTE 0x0000000a 33 + 34 + #define PS3AV_CID_AV_VIDEO_CS 0x00010001 35 + #define PS3AV_CID_AV_VIDEO_MUTE 0x00010002 36 + #define PS3AV_CID_AV_VIDEO_DISABLE_SIG 0x00010003 37 + #define PS3AV_CID_AV_AUDIO_PARAM 0x00020001 38 + #define PS3AV_CID_AV_AUDIO_MUTE 0x00020002 39 + #define PS3AV_CID_AV_HDMI_MODE 0x00040001 40 + 41 + #define PS3AV_CID_VIDEO_INIT 0x01000001 42 + #define PS3AV_CID_VIDEO_MODE 0x01000002 43 + #define PS3AV_CID_VIDEO_FORMAT 0x01000004 44 + #define PS3AV_CID_VIDEO_PITCH 0x01000005 45 + 46 + #define PS3AV_CID_AUDIO_INIT 0x02000001 47 + #define PS3AV_CID_AUDIO_MODE 0x02000002 48 + #define PS3AV_CID_AUDIO_MUTE 0x02000003 49 + #define PS3AV_CID_AUDIO_ACTIVE 0x02000004 50 + #define PS3AV_CID_AUDIO_INACTIVE 0x02000005 51 + #define PS3AV_CID_AUDIO_SPDIF_BIT 0x02000006 52 + #define PS3AV_CID_AUDIO_CTRL 0x02000007 53 + 54 + #define PS3AV_CID_EVENT_UNPLUGGED 0x10000001 55 + #define PS3AV_CID_EVENT_PLUGGED 0x10000002 56 + #define PS3AV_CID_EVENT_HDCP_DONE 0x10000003 57 + #define PS3AV_CID_EVENT_HDCP_FAIL 0x10000004 58 + #define PS3AV_CID_EVENT_HDCP_AUTH 0x10000005 59 + #define PS3AV_CID_EVENT_HDCP_ERROR 0x10000006 60 + 61 + #define PS3AV_CID_AVB_PARAM 0x04000001 62 + 63 + /* max backend ports */ 64 + #define PS3AV_HDMI_MAX 2 /* HDMI_0 HDMI_1 */ 65 + #define PS3AV_AVMULTI_MAX 1 /* AVMULTI_0 */ 66 + #define PS3AV_AV_PORT_MAX (PS3AV_HDMI_MAX + PS3AV_AVMULTI_MAX) 67 + #define PS3AV_OPT_PORT_MAX 1 /* SPDIF0 */ 68 + #define PS3AV_HEAD_MAX 2 /* HEAD_A HEAD_B */ 69 + 70 + /* num of pkt for PS3AV_CID_AVB_PARAM */ 71 + #define PS3AV_AVB_NUM_VIDEO PS3AV_HEAD_MAX 72 + #define PS3AV_AVB_NUM_AUDIO 0 /* not supported */ 73 + #define PS3AV_AVB_NUM_AV_VIDEO PS3AV_AV_PORT_MAX 74 + #define PS3AV_AVB_NUM_AV_AUDIO PS3AV_HDMI_MAX 75 + 76 + #define PS3AV_MUTE_PORT_MAX 1 /* num of ports in mute pkt */ 77 + 78 + /* event_bit */ 79 + #define PS3AV_CMD_EVENT_BIT_UNPLUGGED (1 << 0) 80 + #define PS3AV_CMD_EVENT_BIT_PLUGGED (1 << 1) 81 + #define PS3AV_CMD_EVENT_BIT_HDCP_DONE (1 << 2) 82 + #define PS3AV_CMD_EVENT_BIT_HDCP_FAIL (1 << 3) 83 + #define PS3AV_CMD_EVENT_BIT_HDCP_REAUTH (1 << 4) 84 + #define PS3AV_CMD_EVENT_BIT_HDCP_TOPOLOGY (1 << 5) 85 + 86 + /* common params */ 87 + /* mute */ 88 + #define PS3AV_CMD_MUTE_OFF 0x0000 89 + #define PS3AV_CMD_MUTE_ON 0x0001 90 + /* avport */ 91 + #define PS3AV_CMD_AVPORT_HDMI_0 0x0000 92 + #define PS3AV_CMD_AVPORT_HDMI_1 0x0001 93 + #define PS3AV_CMD_AVPORT_AVMULTI_0 0x0010 94 + #define PS3AV_CMD_AVPORT_SPDIF_0 0x0020 95 + #define PS3AV_CMD_AVPORT_SPDIF_1 0x0021 96 + 97 + /* for av backend */ 98 + /* av_mclk */ 99 + #define PS3AV_CMD_AV_MCLK_128 0x0000 100 + #define PS3AV_CMD_AV_MCLK_256 0x0001 101 + #define PS3AV_CMD_AV_MCLK_512 0x0003 102 + /* av_inputlen */ 103 + #define PS3AV_CMD_AV_INPUTLEN_16 0x02 104 + #define PS3AV_CMD_AV_INPUTLEN_20 0x0a 105 + #define PS3AV_CMD_AV_INPUTLEN_24 0x0b 106 + /* alayout */ 107 + #define PS3AV_CMD_AV_LAYOUT_32 (1 << 0) 108 + #define PS3AV_CMD_AV_LAYOUT_44 (1 << 1) 109 + #define PS3AV_CMD_AV_LAYOUT_48 (1 << 2) 110 + #define PS3AV_CMD_AV_LAYOUT_88 (1 << 3) 111 + #define PS3AV_CMD_AV_LAYOUT_96 (1 << 4) 112 + #define PS3AV_CMD_AV_LAYOUT_176 (1 << 5) 113 + #define PS3AV_CMD_AV_LAYOUT_192 (1 << 6) 114 + /* hdmi_mode */ 115 + #define PS3AV_CMD_AV_HDMI_MODE_NORMAL 0xff 116 + #define PS3AV_CMD_AV_HDMI_HDCP_OFF 0x01 117 + #define PS3AV_CMD_AV_HDMI_EDID_PASS 0x80 118 + #define PS3AV_CMD_AV_HDMI_DVI 0x40 119 + 120 + /* for video module */ 121 + /* video_head */ 122 + #define PS3AV_CMD_VIDEO_HEAD_A 0x0000 123 + #define PS3AV_CMD_VIDEO_HEAD_B 0x0001 124 + /* video_cs_out video_cs_in */ 125 + #define PS3AV_CMD_VIDEO_CS_NONE 0x0000 126 + #define PS3AV_CMD_VIDEO_CS_RGB_8 0x0001 127 + #define PS3AV_CMD_VIDEO_CS_YUV444_8 0x0002 128 + #define PS3AV_CMD_VIDEO_CS_YUV422_8 0x0003 129 + #define PS3AV_CMD_VIDEO_CS_XVYCC_8 0x0004 130 + #define PS3AV_CMD_VIDEO_CS_RGB_10 0x0005 131 + #define PS3AV_CMD_VIDEO_CS_YUV444_10 0x0006 132 + #define PS3AV_CMD_VIDEO_CS_YUV422_10 0x0007 133 + #define PS3AV_CMD_VIDEO_CS_XVYCC_10 0x0008 134 + #define PS3AV_CMD_VIDEO_CS_RGB_12 0x0009 135 + #define PS3AV_CMD_VIDEO_CS_YUV444_12 0x000a 136 + #define PS3AV_CMD_VIDEO_CS_YUV422_12 0x000b 137 + #define PS3AV_CMD_VIDEO_CS_XVYCC_12 0x000c 138 + /* video_vid */ 139 + #define PS3AV_CMD_VIDEO_VID_NONE 0x0000 140 + #define PS3AV_CMD_VIDEO_VID_480I 0x0001 141 + #define PS3AV_CMD_VIDEO_VID_576I 0x0003 142 + #define PS3AV_CMD_VIDEO_VID_480P 0x0005 143 + #define PS3AV_CMD_VIDEO_VID_576P 0x0006 144 + #define PS3AV_CMD_VIDEO_VID_1080I_60HZ 0x0007 145 + #define PS3AV_CMD_VIDEO_VID_1080I_50HZ 0x0008 146 + #define PS3AV_CMD_VIDEO_VID_720P_60HZ 0x0009 147 + #define PS3AV_CMD_VIDEO_VID_720P_50HZ 0x000a 148 + #define PS3AV_CMD_VIDEO_VID_1080P_60HZ 0x000b 149 + #define PS3AV_CMD_VIDEO_VID_1080P_50HZ 0x000c 150 + #define PS3AV_CMD_VIDEO_VID_WXGA 0x000d 151 + #define PS3AV_CMD_VIDEO_VID_SXGA 0x000e 152 + #define PS3AV_CMD_VIDEO_VID_WUXGA 0x000f 153 + #define PS3AV_CMD_VIDEO_VID_480I_A 0x0010 154 + /* video_format */ 155 + #define PS3AV_CMD_VIDEO_FORMAT_BLACK 0x0000 156 + #define PS3AV_CMD_VIDEO_FORMAT_ARGB_8BIT 0x0007 157 + /* video_order */ 158 + #define PS3AV_CMD_VIDEO_ORDER_RGB 0x0000 159 + #define PS3AV_CMD_VIDEO_ORDER_BGR 0x0001 160 + /* video_fmt */ 161 + #define PS3AV_CMD_VIDEO_FMT_X8R8G8B8 0x0000 162 + /* video_out_format */ 163 + #define PS3AV_CMD_VIDEO_OUT_FORMAT_RGB_12BIT 0x0000 164 + /* video_sync */ 165 + #define PS3AV_CMD_VIDEO_SYNC_VSYNC 0x0001 166 + #define PS3AV_CMD_VIDEO_SYNC_CSYNC 0x0004 167 + #define PS3AV_CMD_VIDEO_SYNC_HSYNC 0x0010 168 + 169 + /* for audio module */ 170 + /* num_of_ch */ 171 + #define PS3AV_CMD_AUDIO_NUM_OF_CH_2 0x0000 172 + #define PS3AV_CMD_AUDIO_NUM_OF_CH_3 0x0001 173 + #define PS3AV_CMD_AUDIO_NUM_OF_CH_4 0x0002 174 + #define PS3AV_CMD_AUDIO_NUM_OF_CH_5 0x0003 175 + #define PS3AV_CMD_AUDIO_NUM_OF_CH_6 0x0004 176 + #define PS3AV_CMD_AUDIO_NUM_OF_CH_7 0x0005 177 + #define PS3AV_CMD_AUDIO_NUM_OF_CH_8 0x0006 178 + /* audio_fs */ 179 + #define PS3AV_CMD_AUDIO_FS_32K 0x0001 180 + #define PS3AV_CMD_AUDIO_FS_44K 0x0002 181 + #define PS3AV_CMD_AUDIO_FS_48K 0x0003 182 + #define PS3AV_CMD_AUDIO_FS_88K 0x0004 183 + #define PS3AV_CMD_AUDIO_FS_96K 0x0005 184 + #define PS3AV_CMD_AUDIO_FS_176K 0x0006 185 + #define PS3AV_CMD_AUDIO_FS_192K 0x0007 186 + /* audio_word_bits */ 187 + #define PS3AV_CMD_AUDIO_WORD_BITS_16 0x0001 188 + #define PS3AV_CMD_AUDIO_WORD_BITS_20 0x0002 189 + #define PS3AV_CMD_AUDIO_WORD_BITS_24 0x0003 190 + /* audio_format */ 191 + #define PS3AV_CMD_AUDIO_FORMAT_PCM 0x0001 192 + #define PS3AV_CMD_AUDIO_FORMAT_BITSTREAM 0x00ff 193 + /* audio_source */ 194 + #define PS3AV_CMD_AUDIO_SOURCE_SERIAL 0x0000 195 + #define PS3AV_CMD_AUDIO_SOURCE_SPDIF 0x0001 196 + /* audio_swap */ 197 + #define PS3AV_CMD_AUDIO_SWAP_0 0x0000 198 + #define PS3AV_CMD_AUDIO_SWAP_1 0x0000 199 + /* audio_map */ 200 + #define PS3AV_CMD_AUDIO_MAP_OUTPUT_0 0x0000 201 + #define PS3AV_CMD_AUDIO_MAP_OUTPUT_1 0x0001 202 + #define PS3AV_CMD_AUDIO_MAP_OUTPUT_2 0x0002 203 + #define PS3AV_CMD_AUDIO_MAP_OUTPUT_3 0x0003 204 + /* audio_layout */ 205 + #define PS3AV_CMD_AUDIO_LAYOUT_2CH 0x0000 206 + #define PS3AV_CMD_AUDIO_LAYOUT_6CH 0x000b /* LREClr */ 207 + #define PS3AV_CMD_AUDIO_LAYOUT_8CH 0x001f /* LREClrXY */ 208 + /* audio_downmix */ 209 + #define PS3AV_CMD_AUDIO_DOWNMIX_PERMITTED 0x0000 210 + #define PS3AV_CMD_AUDIO_DOWNMIX_PROHIBITED 0x0001 211 + 212 + /* audio_port */ 213 + #define PS3AV_CMD_AUDIO_PORT_HDMI_0 ( 1 << 0 ) 214 + #define PS3AV_CMD_AUDIO_PORT_HDMI_1 ( 1 << 1 ) 215 + #define PS3AV_CMD_AUDIO_PORT_AVMULTI_0 ( 1 << 10 ) 216 + #define PS3AV_CMD_AUDIO_PORT_SPDIF_0 ( 1 << 20 ) 217 + #define PS3AV_CMD_AUDIO_PORT_SPDIF_1 ( 1 << 21 ) 218 + 219 + /* audio_ctrl_id */ 220 + #define PS3AV_CMD_AUDIO_CTRL_ID_DAC_RESET 0x0000 221 + #define PS3AV_CMD_AUDIO_CTRL_ID_DAC_DE_EMPHASIS 0x0001 222 + #define PS3AV_CMD_AUDIO_CTRL_ID_AVCLK 0x0002 223 + /* audio_ctrl_data[0] reset */ 224 + #define PS3AV_CMD_AUDIO_CTRL_RESET_NEGATE 0x0000 225 + #define PS3AV_CMD_AUDIO_CTRL_RESET_ASSERT 0x0001 226 + /* audio_ctrl_data[0] de-emphasis */ 227 + #define PS3AV_CMD_AUDIO_CTRL_DE_EMPHASIS_OFF 0x0000 228 + #define PS3AV_CMD_AUDIO_CTRL_DE_EMPHASIS_ON 0x0001 229 + /* audio_ctrl_data[0] avclk */ 230 + #define PS3AV_CMD_AUDIO_CTRL_AVCLK_22 0x0000 231 + #define PS3AV_CMD_AUDIO_CTRL_AVCLK_18 0x0001 232 + 233 + /* av_vid */ 234 + /* do not use these params directly, use vid_video2av */ 235 + #define PS3AV_CMD_AV_VID_480I 0x0000 236 + #define PS3AV_CMD_AV_VID_480P 0x0001 237 + #define PS3AV_CMD_AV_VID_720P_60HZ 0x0002 238 + #define PS3AV_CMD_AV_VID_1080I_60HZ 0x0003 239 + #define PS3AV_CMD_AV_VID_1080P_60HZ 0x0004 240 + #define PS3AV_CMD_AV_VID_576I 0x0005 241 + #define PS3AV_CMD_AV_VID_576P 0x0006 242 + #define PS3AV_CMD_AV_VID_720P_50HZ 0x0007 243 + #define PS3AV_CMD_AV_VID_1080I_50HZ 0x0008 244 + #define PS3AV_CMD_AV_VID_1080P_50HZ 0x0009 245 + #define PS3AV_CMD_AV_VID_WXGA 0x000a 246 + #define PS3AV_CMD_AV_VID_SXGA 0x000b 247 + #define PS3AV_CMD_AV_VID_WUXGA 0x000c 248 + /* av_cs_out av_cs_in */ 249 + /* use cs_video2av() */ 250 + #define PS3AV_CMD_AV_CS_RGB_8 0x0000 251 + #define PS3AV_CMD_AV_CS_YUV444_8 0x0001 252 + #define PS3AV_CMD_AV_CS_YUV422_8 0x0002 253 + #define PS3AV_CMD_AV_CS_XVYCC_8 0x0003 254 + #define PS3AV_CMD_AV_CS_RGB_10 0x0004 255 + #define PS3AV_CMD_AV_CS_YUV444_10 0x0005 256 + #define PS3AV_CMD_AV_CS_YUV422_10 0x0006 257 + #define PS3AV_CMD_AV_CS_XVYCC_10 0x0007 258 + #define PS3AV_CMD_AV_CS_RGB_12 0x0008 259 + #define PS3AV_CMD_AV_CS_YUV444_12 0x0009 260 + #define PS3AV_CMD_AV_CS_YUV422_12 0x000a 261 + #define PS3AV_CMD_AV_CS_XVYCC_12 0x000b 262 + #define PS3AV_CMD_AV_CS_8 0x0000 263 + #define PS3AV_CMD_AV_CS_10 0x0001 264 + #define PS3AV_CMD_AV_CS_12 0x0002 265 + /* dither */ 266 + #define PS3AV_CMD_AV_DITHER_OFF 0x0000 267 + #define PS3AV_CMD_AV_DITHER_ON 0x0001 268 + #define PS3AV_CMD_AV_DITHER_8BIT 0x0000 269 + #define PS3AV_CMD_AV_DITHER_10BIT 0x0002 270 + #define PS3AV_CMD_AV_DITHER_12BIT 0x0004 271 + /* super_white */ 272 + #define PS3AV_CMD_AV_SUPER_WHITE_OFF 0x0000 273 + #define PS3AV_CMD_AV_SUPER_WHITE_ON 0x0001 274 + /* aspect */ 275 + #define PS3AV_CMD_AV_ASPECT_16_9 0x0000 276 + #define PS3AV_CMD_AV_ASPECT_4_3 0x0001 277 + /* video_cs_cnv() */ 278 + #define PS3AV_CMD_VIDEO_CS_RGB 0x0001 279 + #define PS3AV_CMD_VIDEO_CS_YUV422 0x0002 280 + #define PS3AV_CMD_VIDEO_CS_YUV444 0x0003 281 + 282 + /* for automode */ 283 + #define PS3AV_RESBIT_720x480P 0x0003 /* 0x0001 | 0x0002 */ 284 + #define PS3AV_RESBIT_720x576P 0x0003 /* 0x0001 | 0x0002 */ 285 + #define PS3AV_RESBIT_1280x720P 0x0004 286 + #define PS3AV_RESBIT_1920x1080I 0x0008 287 + #define PS3AV_RESBIT_1920x1080P 0x4000 288 + #define PS3AV_RES_MASK_60 (PS3AV_RESBIT_720x480P \ 289 + | PS3AV_RESBIT_1280x720P \ 290 + | PS3AV_RESBIT_1920x1080I \ 291 + | PS3AV_RESBIT_1920x1080P) 292 + #define PS3AV_RES_MASK_50 (PS3AV_RESBIT_720x576P \ 293 + | PS3AV_RESBIT_1280x720P \ 294 + | PS3AV_RESBIT_1920x1080I \ 295 + | PS3AV_RESBIT_1920x1080P) 296 + 297 + #define PS3AV_MONITOR_TYPE_HDMI 1 /* HDMI */ 298 + #define PS3AV_MONITOR_TYPE_DVI 2 /* DVI */ 299 + #define PS3AV_DEFAULT_HDMI_VID_REG_60 PS3AV_CMD_VIDEO_VID_480P 300 + #define PS3AV_DEFAULT_AVMULTI_VID_REG_60 PS3AV_CMD_VIDEO_VID_480I 301 + #define PS3AV_DEFAULT_HDMI_VID_REG_50 PS3AV_CMD_VIDEO_VID_576P 302 + #define PS3AV_DEFAULT_AVMULTI_VID_REG_50 PS3AV_CMD_VIDEO_VID_576I 303 + #define PS3AV_DEFAULT_DVI_VID PS3AV_CMD_VIDEO_VID_480P 304 + 305 + #define PS3AV_REGION_60 0x01 306 + #define PS3AV_REGION_50 0x02 307 + #define PS3AV_REGION_RGB 0x10 308 + 309 + #define get_status(buf) (((__u32 *)buf)[2]) 310 + #define PS3AV_HDR_SIZE 4 /* version + size */ 311 + 312 + /* for video mode */ 313 + #define PS3AV_MODE_MASK 0x000F 314 + #define PS3AV_MODE_HDCP_OFF 0x1000 /* Retail PS3 product doesn't support this */ 315 + #define PS3AV_MODE_DITHER 0x0800 316 + #define PS3AV_MODE_FULL 0x0080 317 + #define PS3AV_MODE_DVI 0x0040 318 + #define PS3AV_MODE_RGB 0x0020 319 + 320 + 321 + /** command packet structure **/ 322 + struct ps3av_send_hdr { 323 + u16 version; 324 + u16 size; /* size of command packet */ 325 + u32 cid; /* command id */ 326 + }; 327 + 328 + struct ps3av_reply_hdr { 329 + u16 version; 330 + u16 size; 331 + u32 cid; 332 + u32 status; 333 + }; 334 + 335 + /* backend: initialization */ 336 + struct ps3av_pkt_av_init { 337 + struct ps3av_send_hdr send_hdr; 338 + u32 event_bit; 339 + }; 340 + 341 + /* backend: finalize */ 342 + struct ps3av_pkt_av_fin { 343 + struct ps3av_send_hdr send_hdr; 344 + /* recv */ 345 + u32 reserved; 346 + }; 347 + 348 + /* backend: get port */ 349 + struct ps3av_pkt_av_get_hw_conf { 350 + struct ps3av_send_hdr send_hdr; 351 + /* recv */ 352 + u32 status; 353 + u16 num_of_hdmi; /* out: number of hdmi */ 354 + u16 num_of_avmulti; /* out: number of avmulti */ 355 + u16 num_of_spdif; /* out: number of hdmi */ 356 + u16 reserved; 357 + }; 358 + 359 + /* backend: get monitor info */ 360 + struct ps3av_info_resolution { 361 + u32 res_bits; 362 + u32 native; 363 + }; 364 + 365 + struct ps3av_info_cs { 366 + u8 rgb; 367 + u8 yuv444; 368 + u8 yuv422; 369 + u8 reserved; 370 + }; 371 + 372 + struct ps3av_info_color { 373 + u16 red_x; 374 + u16 red_y; 375 + u16 green_x; 376 + u16 green_y; 377 + u16 blue_x; 378 + u16 blue_y; 379 + u16 white_x; 380 + u16 white_y; 381 + u32 gamma; 382 + }; 383 + 384 + struct ps3av_info_audio { 385 + u8 type; 386 + u8 max_num_of_ch; 387 + u8 fs; 388 + u8 sbit; 389 + }; 390 + 391 + struct ps3av_info_monitor { 392 + u8 avport; 393 + u8 monitor_id[10]; 394 + u8 monitor_type; 395 + u8 monitor_name[16]; 396 + struct ps3av_info_resolution res_60; 397 + struct ps3av_info_resolution res_50; 398 + struct ps3av_info_resolution res_other; 399 + struct ps3av_info_resolution res_vesa; 400 + struct ps3av_info_cs cs; 401 + struct ps3av_info_color color; 402 + u8 supported_ai; 403 + u8 speaker_info; 404 + u8 num_of_audio_block; 405 + struct ps3av_info_audio audio[0]; /* 0 or more audio blocks */ 406 + u8 reserved[169]; 407 + } __attribute__ ((packed)); 408 + 409 + struct ps3av_pkt_av_get_monitor_info { 410 + struct ps3av_send_hdr send_hdr; 411 + u16 avport; /* in: avport */ 412 + u16 reserved; 413 + /* recv */ 414 + struct ps3av_info_monitor info; /* out: monitor info */ 415 + }; 416 + 417 + /* backend: enable/disable event */ 418 + struct ps3av_pkt_av_event { 419 + struct ps3av_send_hdr send_hdr; 420 + u32 event_bit; /* in */ 421 + }; 422 + 423 + /* backend: video cs param */ 424 + struct ps3av_pkt_av_video_cs { 425 + struct ps3av_send_hdr send_hdr; 426 + u16 avport; /* in: avport */ 427 + u16 av_vid; /* in: video resolution */ 428 + u16 av_cs_out; /* in: output color space */ 429 + u16 av_cs_in; /* in: input color space */ 430 + u8 dither; /* in: dither bit length */ 431 + u8 bitlen_out; /* in: bit length */ 432 + u8 super_white; /* in: super white */ 433 + u8 aspect; /* in: aspect ratio */ 434 + }; 435 + 436 + /* backend: video mute */ 437 + struct ps3av_av_mute { 438 + u16 avport; /* in: avport */ 439 + u16 mute; /* in: mute on/off */ 440 + }; 441 + 442 + struct ps3av_pkt_av_video_mute { 443 + struct ps3av_send_hdr send_hdr; 444 + struct ps3av_av_mute mute[PS3AV_MUTE_PORT_MAX]; 445 + }; 446 + 447 + /* backend: video disable signal */ 448 + struct ps3av_pkt_av_video_disable_sig { 449 + struct ps3av_send_hdr send_hdr; 450 + u16 avport; /* in: avport */ 451 + u16 reserved; 452 + }; 453 + 454 + /* backend: audio param */ 455 + struct ps3av_audio_info_frame { 456 + struct pb1_bit { 457 + u8 ct:4; 458 + u8 rsv:1; 459 + u8 cc:3; 460 + } pb1; 461 + struct pb2_bit { 462 + u8 rsv:3; 463 + u8 sf:3; 464 + u8 ss:2; 465 + } pb2; 466 + u8 pb3; 467 + u8 pb4; 468 + struct pb5_bit { 469 + u8 dm:1; 470 + u8 lsv:4; 471 + u8 rsv:3; 472 + } pb5; 473 + }; 474 + 475 + struct ps3av_pkt_av_audio_param { 476 + struct ps3av_send_hdr send_hdr; 477 + u16 avport; /* in: avport */ 478 + u16 reserved; 479 + u8 mclk; /* in: audio mclk */ 480 + u8 ns[3]; /* in: audio ns val */ 481 + u8 enable; /* in: audio enable */ 482 + u8 swaplr; /* in: audio swap */ 483 + u8 fifomap; /* in: audio fifomap */ 484 + u8 inputctrl; /* in: audio input ctrl */ 485 + u8 inputlen; /* in: sample bit size */ 486 + u8 layout; /* in: speaker layout param */ 487 + struct ps3av_audio_info_frame info; /* in: info */ 488 + u8 chstat[5]; /* in: ch stat */ 489 + }; 490 + 491 + /* backend: audio_mute */ 492 + struct ps3av_pkt_av_audio_mute { 493 + struct ps3av_send_hdr send_hdr; 494 + struct ps3av_av_mute mute[PS3AV_MUTE_PORT_MAX]; 495 + }; 496 + 497 + /* backend: hdmi_mode */ 498 + struct ps3av_pkt_av_hdmi_mode { 499 + struct ps3av_send_hdr send_hdr; 500 + u8 mode; /* in: hdmi_mode */ 501 + u8 reserved0; 502 + u8 reserved1; 503 + u8 reserved2; 504 + }; 505 + 506 + /* backend: tv_mute */ 507 + struct ps3av_pkt_av_tv_mute { 508 + struct ps3av_send_hdr send_hdr; 509 + u16 avport; /* in: avport HDMI only */ 510 + u16 mute; /* in: mute */ 511 + }; 512 + 513 + /* video: initialize */ 514 + struct ps3av_pkt_video_init { 515 + struct ps3av_send_hdr send_hdr; 516 + /* recv */ 517 + u32 reserved; 518 + }; 519 + 520 + /* video: mode setting */ 521 + struct ps3av_pkt_video_mode { 522 + struct ps3av_send_hdr send_hdr; 523 + u32 video_head; /* in: head */ 524 + u32 reserved; 525 + u32 video_vid; /* in: video resolution */ 526 + u16 reserved1; 527 + u16 width; /* in: width in pixel */ 528 + u16 reserved2; 529 + u16 height; /* in: height in pixel */ 530 + u32 pitch; /* in: line size in byte */ 531 + u32 video_out_format; /* in: out format */ 532 + u32 video_format; /* in: input frame buffer format */ 533 + u8 reserved3; 534 + u8 reserved4; 535 + u16 video_order; /* in: input RGB order */ 536 + u32 reserved5; 537 + }; 538 + 539 + /* video: format */ 540 + struct ps3av_pkt_video_format { 541 + struct ps3av_send_hdr send_hdr; 542 + u32 video_head; /* in: head */ 543 + u32 video_format; /* in: frame buffer format */ 544 + u16 reserved; 545 + u16 video_order; /* in: input RGB order */ 546 + }; 547 + 548 + /* video: pitch */ 549 + struct ps3av_pkt_video_pitch { 550 + u16 version; 551 + u16 size; /* size of command packet */ 552 + u32 cid; /* command id */ 553 + u32 video_head; /* in: head */ 554 + u32 pitch; /* in: line size in byte */ 555 + }; 556 + 557 + /* audio: initialize */ 558 + struct ps3av_pkt_audio_init { 559 + struct ps3av_send_hdr send_hdr; 560 + /* recv */ 561 + u32 reserved; 562 + }; 563 + 564 + /* audio: mode setting */ 565 + struct ps3av_pkt_audio_mode { 566 + struct ps3av_send_hdr send_hdr; 567 + u8 avport; /* in: avport */ 568 + u8 reserved0[3]; 569 + u32 mask; /* in: mask */ 570 + u32 audio_num_of_ch; /* in: number of ch */ 571 + u32 audio_fs; /* in: sampling freq */ 572 + u32 audio_word_bits; /* in: sample bit size */ 573 + u32 audio_format; /* in: audio output format */ 574 + u32 audio_source; /* in: audio source */ 575 + u8 audio_enable[4]; /* in: audio enable */ 576 + u8 audio_swap[4]; /* in: audio swap */ 577 + u8 audio_map[4]; /* in: audio map */ 578 + u32 audio_layout; /* in: speaker layout */ 579 + u32 audio_downmix; /* in: audio downmix permission */ 580 + u32 audio_downmix_level; 581 + u8 audio_cs_info[8]; /* in: IEC channel status */ 582 + }; 583 + 584 + /* audio: mute */ 585 + struct ps3av_audio_mute { 586 + u8 avport; /* in: opt_port optical */ 587 + u8 reserved[3]; 588 + u32 mute; /* in: mute */ 589 + }; 590 + 591 + struct ps3av_pkt_audio_mute { 592 + struct ps3av_send_hdr send_hdr; 593 + struct ps3av_audio_mute mute[PS3AV_OPT_PORT_MAX]; 594 + }; 595 + 596 + /* audio: active/inactive */ 597 + struct ps3av_pkt_audio_active { 598 + struct ps3av_send_hdr send_hdr; 599 + u32 audio_port; /* in: audio active/inactive port */ 600 + }; 601 + 602 + /* audio: SPDIF user bit */ 603 + struct ps3av_pkt_audio_spdif_bit { 604 + u16 version; 605 + u16 size; /* size of command packet */ 606 + u32 cid; /* command id */ 607 + u8 avport; /* in: avport SPDIF only */ 608 + u8 reserved[3]; 609 + u32 audio_port; /* in: SPDIF only */ 610 + u32 spdif_bit_data[12]; /* in: user bit data */ 611 + }; 612 + 613 + /* audio: audio control */ 614 + struct ps3av_pkt_audio_ctrl { 615 + u16 version; 616 + u16 size; /* size of command packet */ 617 + u32 cid; /* command id */ 618 + u32 audio_ctrl_id; /* in: control id */ 619 + u32 audio_ctrl_data[4]; /* in: control data */ 620 + }; 621 + 622 + /* avb:param */ 623 + #define PS3AV_PKT_AVB_PARAM_MAX_BUF_SIZE \ 624 + (PS3AV_AVB_NUM_VIDEO*sizeof(struct ps3av_pkt_video_mode) + \ 625 + PS3AV_AVB_NUM_AUDIO*sizeof(struct ps3av_pkt_audio_mode) + \ 626 + PS3AV_AVB_NUM_AV_VIDEO*sizeof(struct ps3av_pkt_av_video_cs) + \ 627 + PS3AV_AVB_NUM_AV_AUDIO*sizeof(struct ps3av_pkt_av_audio_param)) 628 + 629 + struct ps3av_pkt_avb_param { 630 + struct ps3av_send_hdr send_hdr; 631 + u16 num_of_video_pkt; 632 + u16 num_of_audio_pkt; 633 + u16 num_of_av_video_pkt; 634 + u16 num_of_av_audio_pkt; 635 + /* 636 + * The actual buffer layout depends on the fields above: 637 + * 638 + * struct ps3av_pkt_video_mode video[num_of_video_pkt]; 639 + * struct ps3av_pkt_audio_mode audio[num_of_audio_pkt]; 640 + * struct ps3av_pkt_av_video_cs av_video[num_of_av_video_pkt]; 641 + * struct ps3av_pkt_av_audio_param av_audio[num_of_av_audio_pkt]; 642 + */ 643 + u8 buf[PS3AV_PKT_AVB_PARAM_MAX_BUF_SIZE]; 644 + }; 645 + 646 + struct ps3av { 647 + int available; 648 + struct semaphore sem; 649 + struct semaphore ping; 650 + struct semaphore pong; 651 + struct mutex mutex; 652 + int open_count; 653 + struct ps3_vuart_port_device *dev; 654 + 655 + int region; 656 + struct ps3av_pkt_av_get_hw_conf av_hw_conf; 657 + u32 av_port[PS3AV_AV_PORT_MAX + PS3AV_OPT_PORT_MAX]; 658 + u32 opt_port[PS3AV_OPT_PORT_MAX]; 659 + u32 head[PS3AV_HEAD_MAX]; 660 + u32 audio_port; 661 + int ps3av_mode; 662 + int ps3av_mode_old; 663 + }; 664 + 665 + /** command status **/ 666 + #define PS3AV_STATUS_SUCCESS 0x0000 /* success */ 667 + #define PS3AV_STATUS_RECEIVE_VUART_ERROR 0x0001 /* receive vuart error */ 668 + #define PS3AV_STATUS_SYSCON_COMMUNICATE_FAIL 0x0002 /* syscon communication error */ 669 + #define PS3AV_STATUS_INVALID_COMMAND 0x0003 /* obsolete invalid CID */ 670 + #define PS3AV_STATUS_INVALID_PORT 0x0004 /* invalid port number */ 671 + #define PS3AV_STATUS_INVALID_VID 0x0005 /* invalid video format */ 672 + #define PS3AV_STATUS_INVALID_COLOR_SPACE 0x0006 /* invalid video colose space */ 673 + #define PS3AV_STATUS_INVALID_FS 0x0007 /* invalid audio sampling freq */ 674 + #define PS3AV_STATUS_INVALID_AUDIO_CH 0x0008 /* invalid audio channel number */ 675 + #define PS3AV_STATUS_UNSUPPORTED_VERSION 0x0009 /* version mismatch */ 676 + #define PS3AV_STATUS_INVALID_SAMPLE_SIZE 0x000a /* invalid audio sample bit size */ 677 + #define PS3AV_STATUS_FAILURE 0x000b /* other failures */ 678 + #define PS3AV_STATUS_UNSUPPORTED_COMMAND 0x000c /* unsupported cid */ 679 + #define PS3AV_STATUS_BUFFER_OVERFLOW 0x000d /* write buffer overflow */ 680 + #define PS3AV_STATUS_INVALID_VIDEO_PARAM 0x000e /* invalid video param */ 681 + #define PS3AV_STATUS_NO_SEL 0x000f /* not exist selector */ 682 + #define PS3AV_STATUS_INVALID_AV_PARAM 0x0010 /* invalid backend param */ 683 + #define PS3AV_STATUS_INVALID_AUDIO_PARAM 0x0011 /* invalid audio param */ 684 + #define PS3AV_STATUS_UNSUPPORTED_HDMI_MODE 0x0012 /* unsupported hdmi mode */ 685 + #define PS3AV_STATUS_NO_SYNC_HEAD 0x0013 /* sync head failed */ 686 + 687 + extern void ps3av_set_hdr(u32, u16, struct ps3av_send_hdr *); 688 + extern int ps3av_do_pkt(u32, u16, size_t, struct ps3av_send_hdr *); 689 + 690 + extern int ps3av_cmd_init(void); 691 + extern int ps3av_cmd_fin(void); 692 + extern int ps3av_cmd_av_video_mute(int, u32 *, u32); 693 + extern int ps3av_cmd_av_video_disable_sig(u32); 694 + extern int ps3av_cmd_av_tv_mute(u32, u32); 695 + extern int ps3av_cmd_enable_event(void); 696 + extern int ps3av_cmd_av_hdmi_mode(u8); 697 + extern u32 ps3av_cmd_set_av_video_cs(void *, u32, int, int, int, u32); 698 + extern u32 ps3av_cmd_set_video_mode(void *, u32, int, int, u32); 699 + extern int ps3av_cmd_video_format_black(u32, u32, u32); 700 + extern int ps3av_cmd_av_audio_mute(int, u32 *, u32); 701 + extern u32 ps3av_cmd_set_av_audio_param(void *, u32, 702 + const struct ps3av_pkt_audio_mode *, 703 + u32); 704 + extern void ps3av_cmd_set_audio_mode(struct ps3av_pkt_audio_mode *, u32, u32, 705 + u32, u32, u32, u32); 706 + extern int ps3av_cmd_audio_mode(struct ps3av_pkt_audio_mode *); 707 + extern int ps3av_cmd_audio_mute(int, u32 *, u32); 708 + extern int ps3av_cmd_audio_active(int, u32); 709 + extern int ps3av_cmd_avb_param(struct ps3av_pkt_avb_param *, u32); 710 + extern int ps3av_cmd_av_get_hw_conf(struct ps3av_pkt_av_get_hw_conf *); 711 + #ifdef PS3AV_DEBUG 712 + extern void ps3av_cmd_av_hw_conf_dump(const struct ps3av_pkt_av_get_hw_conf *); 713 + extern void ps3av_cmd_av_monitor_info_dump(const struct ps3av_pkt_av_get_monitor_info *); 714 + #else 715 + static inline void ps3av_cmd_av_hw_conf_dump(const struct ps3av_pkt_av_get_hw_conf *hw_conf) {} 716 + static inline void ps3av_cmd_av_monitor_info_dump(const struct ps3av_pkt_av_get_monitor_info *monitor_info) {} 717 + #endif 718 + extern int ps3av_cmd_video_get_monitor_info(struct ps3av_pkt_av_get_monitor_info *, 719 + u32); 720 + 721 + extern int ps3av_vuart_write(struct ps3_vuart_port_device *dev, 722 + const void *buf, unsigned long size); 723 + extern int ps3av_vuart_read(struct ps3_vuart_port_device *dev, void *buf, 724 + unsigned long size, int timeout); 725 + 726 + extern int ps3av_set_video_mode(u32, int); 727 + extern int ps3av_set_audio_mode(u32, u32, u32, u32, u32); 728 + extern int ps3av_set_mode(u32, int); 729 + extern int ps3av_get_mode(void); 730 + extern int ps3av_get_scanmode(int); 731 + extern int ps3av_get_refresh_rate(int); 732 + extern int ps3av_video_mode2res(u32, u32 *, u32 *); 733 + extern int ps3av_video_mute(int); 734 + extern int ps3av_audio_mute(int); 735 + extern int ps3av_dev_open(void); 736 + extern int ps3av_dev_close(void); 737 + 738 + #endif /* _ASM_POWERPC_PS3AV_H_ */