aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ps3/ps3av.c
diff options
context:
space:
mode:
authorGeoff Levand <geoffrey.levand@am.sony.com>2007-06-15 18:05:01 -0400
committerPaul Mackerras <paulus@samba.org>2007-06-28 05:16:42 -0400
commit13a5e30cf7407415387b5592b15ef4b352d28283 (patch)
tree8db7937b82960d0f59f3bbdf4715b347fc7a04d1 /drivers/ps3/ps3av.c
parent66c63b84b23d39ce191a18833b5a769370114ec9 (diff)
[POWERPC] PS3: Rework AV settings driver
Make the PS3 ps3av driver a loadable module. - Replace static data with kmalloc()'ed. o Allocate struct ps3av dynamically, as it contains data used as vuart receive/transmit buffers o Move static recv_buf from ps3av_do_pkt() to struct ps3av - Move ps3av_vuart_{read,write}() from drivers/ps3/ps3av_cmd.c to drivers/ps3/ps3av.c and make them static as they're used in that file only. - Make device a PS3 system-bus device. - Update copyright formatting. - Make two new routines ps3av_register_flip_ctl() and ps3av_flip_ctl() to support late binding of the frame buffer flip control routine. Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com> Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'drivers/ps3/ps3av.c')
-rw-r--r--drivers/ps3/ps3av.c372
1 files changed, 198 insertions, 174 deletions
diff --git a/drivers/ps3/ps3av.c b/drivers/ps3/ps3av.c
index 1393e64335f9..85e21614f868 100644
--- a/drivers/ps3/ps3av.c
+++ b/drivers/ps3/ps3av.c
@@ -1,32 +1,30 @@
1/* 1/*
2 * Copyright (C) 2006 Sony Computer Entertainment Inc. 2 * PS3 AV backend support.
3 * Copyright 2006, 2007 Sony Corporation
4 * 3 *
5 * AV backend support for PS3 4 * Copyright (C) 2007 Sony Computer Entertainment Inc.
5 * Copyright 2007 Sony Corp.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify
8 * under the terms of the GNU General Public License as published 8 * it under the terms of the GNU General Public License as published by
9 * by the Free Software Foundation; version 2 of the License. 9 * the Free Software Foundation; version 2 of the License.
10 * 10 *
11 * This program is distributed in the hope that it will be useful, but 11 * This program is distributed in the hope that it will be useful,
12 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License along 16 * You should have received a copy of the GNU General Public License
17 * with this program; if not, write to the Free Software Foundation, Inc., 17 * along with this program; if not, write to the Free Software
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 19 */
20 20
21#include <linux/kernel.h>
21#include <linux/module.h> 22#include <linux/module.h>
22#include <linux/delay.h> 23#include <linux/delay.h>
23#include <linux/notifier.h> 24#include <linux/notifier.h>
24#include <linux/reboot.h>
25#include <linux/kernel.h>
26#include <linux/ioctl.h> 25#include <linux/ioctl.h>
27 26
28#include <asm/firmware.h> 27#include <asm/firmware.h>
29#include <asm/lv1call.h>
30#include <asm/ps3av.h> 28#include <asm/ps3av.h>
31#include <asm/ps3.h> 29#include <asm/ps3.h>
32 30
@@ -39,13 +37,12 @@ static int timeout = 5000; /* in msec ( 5 sec ) */
39module_param(timeout, int, 0644); 37module_param(timeout, int, 0644);
40 38
41static struct ps3av { 39static struct ps3av {
42 int available;
43 struct mutex mutex; 40 struct mutex mutex;
44 struct work_struct work; 41 struct work_struct work;
45 struct completion done; 42 struct completion done;
46 struct workqueue_struct *wq; 43 struct workqueue_struct *wq;
47 int open_count; 44 int open_count;
48 struct ps3_vuart_port_device *dev; 45 struct ps3_system_bus_device *dev;
49 46
50 int region; 47 int region;
51 struct ps3av_pkt_av_get_hw_conf av_hw_conf; 48 struct ps3av_pkt_av_get_hw_conf av_hw_conf;
@@ -55,11 +52,13 @@ static struct ps3av {
55 u32 audio_port; 52 u32 audio_port;
56 int ps3av_mode; 53 int ps3av_mode;
57 int ps3av_mode_old; 54 int ps3av_mode_old;
58} ps3av; 55 union {
59 56 struct ps3av_reply_hdr reply_hdr;
60static struct ps3_vuart_port_device ps3av_dev = { 57 u8 raw[PS3AV_BUF_SIZE];
61 .match_id = PS3_MATCH_ID_AV_SETTINGS 58 } recv_buf;
62}; 59 void (*flip_ctl)(int on, void *data);
60 void *flip_data;
61} *ps3av;
63 62
64/* color space */ 63/* color space */
65#define YUV444 PS3AV_CMD_VIDEO_CS_YUV444_8 64#define YUV444 PS3AV_CMD_VIDEO_CS_YUV444_8
@@ -169,7 +168,7 @@ static int ps3av_parse_event_packet(const struct ps3av_reply_hdr *hdr)
169 if (hdr->cid & PS3AV_EVENT_CMD_MASK) { 168 if (hdr->cid & PS3AV_EVENT_CMD_MASK) {
170 table = ps3av_search_cmd_table(hdr->cid, PS3AV_EVENT_CMD_MASK); 169 table = ps3av_search_cmd_table(hdr->cid, PS3AV_EVENT_CMD_MASK);
171 if (table) 170 if (table)
172 dev_dbg(&ps3av_dev.core, 171 dev_dbg(&ps3av->dev->core,
173 "recv event packet cid:%08x port:0x%x size:%d\n", 172 "recv event packet cid:%08x port:0x%x size:%d\n",
174 hdr->cid, ps3av_event_get_port_id(hdr->cid), 173 hdr->cid, ps3av_event_get_port_id(hdr->cid),
175 hdr->size); 174 hdr->size);
@@ -182,6 +181,41 @@ static int ps3av_parse_event_packet(const struct ps3av_reply_hdr *hdr)
182 return 0; 181 return 0;
183} 182}
184 183
184
185#define POLLING_INTERVAL 25 /* in msec */
186
187static int ps3av_vuart_write(struct ps3_system_bus_device *dev,
188 const void *buf, unsigned long size)
189{
190 int error;
191 dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
192 error = ps3_vuart_write(dev, buf, size);
193 dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
194 return error ? error : size;
195}
196
197static int ps3av_vuart_read(struct ps3_system_bus_device *dev, void *buf,
198 unsigned long size, int timeout)
199{
200 int error;
201 int loopcnt = 0;
202
203 dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
204 timeout = (timeout + POLLING_INTERVAL - 1) / POLLING_INTERVAL;
205 while (loopcnt++ <= timeout) {
206 error = ps3_vuart_read(dev, buf, size);
207 if (!error)
208 return size;
209 if (error != -EAGAIN) {
210 printk(KERN_ERR "%s: ps3_vuart_read failed %d\n",
211 __func__, error);
212 return error;
213 }
214 msleep(POLLING_INTERVAL);
215 }
216 return -EWOULDBLOCK;
217}
218
185static int ps3av_send_cmd_pkt(const struct ps3av_send_hdr *send_buf, 219static int ps3av_send_cmd_pkt(const struct ps3av_send_hdr *send_buf,
186 struct ps3av_reply_hdr *recv_buf, int write_len, 220 struct ps3av_reply_hdr *recv_buf, int write_len,
187 int read_len) 221 int read_len)
@@ -190,13 +224,13 @@ static int ps3av_send_cmd_pkt(const struct ps3av_send_hdr *send_buf,
190 u32 cmd; 224 u32 cmd;
191 int event; 225 int event;
192 226
193 if (!ps3av.available) 227 if (!ps3av)
194 return -ENODEV; 228 return -ENODEV;
195 229
196 /* send pkt */ 230 /* send pkt */
197 res = ps3av_vuart_write(ps3av.dev, send_buf, write_len); 231 res = ps3av_vuart_write(ps3av->dev, send_buf, write_len);
198 if (res < 0) { 232 if (res < 0) {
199 dev_dbg(&ps3av_dev.core, 233 dev_dbg(&ps3av->dev->core,
200 "%s: ps3av_vuart_write() failed (result=%d)\n", 234 "%s: ps3av_vuart_write() failed (result=%d)\n",
201 __func__, res); 235 __func__, res);
202 return res; 236 return res;
@@ -206,20 +240,20 @@ static int ps3av_send_cmd_pkt(const struct ps3av_send_hdr *send_buf,
206 cmd = send_buf->cid; 240 cmd = send_buf->cid;
207 do { 241 do {
208 /* read header */ 242 /* read header */
209 res = ps3av_vuart_read(ps3av.dev, recv_buf, PS3AV_HDR_SIZE, 243 res = ps3av_vuart_read(ps3av->dev, recv_buf, PS3AV_HDR_SIZE,
210 timeout); 244 timeout);
211 if (res != PS3AV_HDR_SIZE) { 245 if (res != PS3AV_HDR_SIZE) {
212 dev_dbg(&ps3av_dev.core, 246 dev_dbg(&ps3av->dev->core,
213 "%s: ps3av_vuart_read() failed (result=%d)\n", 247 "%s: ps3av_vuart_read() failed (result=%d)\n",
214 __func__, res); 248 __func__, res);
215 return res; 249 return res;
216 } 250 }
217 251
218 /* read body */ 252 /* read body */
219 res = ps3av_vuart_read(ps3av.dev, &recv_buf->cid, 253 res = ps3av_vuart_read(ps3av->dev, &recv_buf->cid,
220 recv_buf->size, timeout); 254 recv_buf->size, timeout);
221 if (res < 0) { 255 if (res < 0) {
222 dev_dbg(&ps3av_dev.core, 256 dev_dbg(&ps3av->dev->core,
223 "%s: ps3av_vuart_read() failed (result=%d)\n", 257 "%s: ps3av_vuart_read() failed (result=%d)\n",
224 __func__, res); 258 __func__, res);
225 return res; 259 return res;
@@ -230,7 +264,7 @@ static int ps3av_send_cmd_pkt(const struct ps3av_send_hdr *send_buf,
230 } while (event); 264 } while (event);
231 265
232 if ((cmd | PS3AV_REPLY_BIT) != recv_buf->cid) { 266 if ((cmd | PS3AV_REPLY_BIT) != recv_buf->cid) {
233 dev_dbg(&ps3av_dev.core, "%s: reply err (result=%x)\n", 267 dev_dbg(&ps3av->dev->core, "%s: reply err (result=%x)\n",
234 __func__, recv_buf->cid); 268 __func__, recv_buf->cid);
235 return -EINVAL; 269 return -EINVAL;
236 } 270 }
@@ -245,7 +279,7 @@ static int ps3av_process_reply_packet(struct ps3av_send_hdr *cmd_buf,
245 int return_len; 279 int return_len;
246 280
247 if (recv_buf->version != PS3AV_VERSION) { 281 if (recv_buf->version != PS3AV_VERSION) {
248 dev_dbg(&ps3av_dev.core, "reply_packet invalid version:%x\n", 282 dev_dbg(&ps3av->dev->core, "reply_packet invalid version:%x\n",
249 recv_buf->version); 283 recv_buf->version);
250 return -EFAULT; 284 return -EFAULT;
251 } 285 }
@@ -267,16 +301,11 @@ int ps3av_do_pkt(u32 cid, u16 send_len, size_t usr_buf_size,
267 struct ps3av_send_hdr *buf) 301 struct ps3av_send_hdr *buf)
268{ 302{
269 int res = 0; 303 int res = 0;
270 static union {
271 struct ps3av_reply_hdr reply_hdr;
272 u8 raw[PS3AV_BUF_SIZE];
273 } recv_buf;
274
275 u32 *table; 304 u32 *table;
276 305
277 BUG_ON(!ps3av.available); 306 BUG_ON(!ps3av);
278 307
279 mutex_lock(&ps3av.mutex); 308 mutex_lock(&ps3av->mutex);
280 309
281 table = ps3av_search_cmd_table(cid, PS3AV_CID_MASK); 310 table = ps3av_search_cmd_table(cid, PS3AV_CID_MASK);
282 BUG_ON(!table); 311 BUG_ON(!table);
@@ -288,7 +317,7 @@ int ps3av_do_pkt(u32 cid, u16 send_len, size_t usr_buf_size,
288 ps3av_set_hdr(cid, send_len, buf); 317 ps3av_set_hdr(cid, send_len, buf);
289 318
290 /* send packet via vuart */ 319 /* send packet via vuart */
291 res = ps3av_send_cmd_pkt(buf, &recv_buf.reply_hdr, send_len, 320 res = ps3av_send_cmd_pkt(buf, &ps3av->recv_buf.reply_hdr, send_len,
292 usr_buf_size); 321 usr_buf_size);
293 if (res < 0) { 322 if (res < 0) {
294 printk(KERN_ERR 323 printk(KERN_ERR
@@ -298,7 +327,7 @@ int ps3av_do_pkt(u32 cid, u16 send_len, size_t usr_buf_size,
298 } 327 }
299 328
300 /* process reply packet */ 329 /* process reply packet */
301 res = ps3av_process_reply_packet(buf, &recv_buf.reply_hdr, 330 res = ps3av_process_reply_packet(buf, &ps3av->recv_buf.reply_hdr,
302 usr_buf_size); 331 usr_buf_size);
303 if (res < 0) { 332 if (res < 0) {
304 printk(KERN_ERR "%s: put_return_status() failed (result=%d)\n", 333 printk(KERN_ERR "%s: put_return_status() failed (result=%d)\n",
@@ -306,11 +335,11 @@ int ps3av_do_pkt(u32 cid, u16 send_len, size_t usr_buf_size,
306 goto err; 335 goto err;
307 } 336 }
308 337
309 mutex_unlock(&ps3av.mutex); 338 mutex_unlock(&ps3av->mutex);
310 return 0; 339 return 0;
311 340
312 err: 341 err:
313 mutex_unlock(&ps3av.mutex); 342 mutex_unlock(&ps3av->mutex);
314 printk(KERN_ERR "%s: failed cid:%x res:%d\n", __func__, cid, res); 343 printk(KERN_ERR "%s: failed cid:%x res:%d\n", __func__, cid, res);
315 return res; 344 return res;
316} 345}
@@ -319,11 +348,11 @@ static int ps3av_set_av_video_mute(u32 mute)
319{ 348{
320 int i, num_of_av_port, res; 349 int i, num_of_av_port, res;
321 350
322 num_of_av_port = ps3av.av_hw_conf.num_of_hdmi + 351 num_of_av_port = ps3av->av_hw_conf.num_of_hdmi +
323 ps3av.av_hw_conf.num_of_avmulti; 352 ps3av->av_hw_conf.num_of_avmulti;
324 /* video mute on */ 353 /* video mute on */
325 for (i = 0; i < num_of_av_port; i++) { 354 for (i = 0; i < num_of_av_port; i++) {
326 res = ps3av_cmd_av_video_mute(1, &ps3av.av_port[i], mute); 355 res = ps3av_cmd_av_video_mute(1, &ps3av->av_port[i], mute);
327 if (res < 0) 356 if (res < 0)
328 return -1; 357 return -1;
329 } 358 }
@@ -335,13 +364,13 @@ static int ps3av_set_video_disable_sig(void)
335{ 364{
336 int i, num_of_hdmi_port, num_of_av_port, res; 365 int i, num_of_hdmi_port, num_of_av_port, res;
337 366
338 num_of_hdmi_port = ps3av.av_hw_conf.num_of_hdmi; 367 num_of_hdmi_port = ps3av->av_hw_conf.num_of_hdmi;
339 num_of_av_port = ps3av.av_hw_conf.num_of_hdmi + 368 num_of_av_port = ps3av->av_hw_conf.num_of_hdmi +
340 ps3av.av_hw_conf.num_of_avmulti; 369 ps3av->av_hw_conf.num_of_avmulti;
341 370
342 /* tv mute */ 371 /* tv mute */
343 for (i = 0; i < num_of_hdmi_port; i++) { 372 for (i = 0; i < num_of_hdmi_port; i++) {
344 res = ps3av_cmd_av_tv_mute(ps3av.av_port[i], 373 res = ps3av_cmd_av_tv_mute(ps3av->av_port[i],
345 PS3AV_CMD_MUTE_ON); 374 PS3AV_CMD_MUTE_ON);
346 if (res < 0) 375 if (res < 0)
347 return -1; 376 return -1;
@@ -350,11 +379,11 @@ static int ps3av_set_video_disable_sig(void)
350 379
351 /* video mute on */ 380 /* video mute on */
352 for (i = 0; i < num_of_av_port; i++) { 381 for (i = 0; i < num_of_av_port; i++) {
353 res = ps3av_cmd_av_video_disable_sig(ps3av.av_port[i]); 382 res = ps3av_cmd_av_video_disable_sig(ps3av->av_port[i]);
354 if (res < 0) 383 if (res < 0)
355 return -1; 384 return -1;
356 if (i < num_of_hdmi_port) { 385 if (i < num_of_hdmi_port) {
357 res = ps3av_cmd_av_tv_mute(ps3av.av_port[i], 386 res = ps3av_cmd_av_tv_mute(ps3av->av_port[i],
358 PS3AV_CMD_MUTE_OFF); 387 PS3AV_CMD_MUTE_OFF);
359 if (res < 0) 388 if (res < 0)
360 return -1; 389 return -1;
@@ -369,17 +398,17 @@ static int ps3av_set_audio_mute(u32 mute)
369{ 398{
370 int i, num_of_av_port, num_of_opt_port, res; 399 int i, num_of_av_port, num_of_opt_port, res;
371 400
372 num_of_av_port = ps3av.av_hw_conf.num_of_hdmi + 401 num_of_av_port = ps3av->av_hw_conf.num_of_hdmi +
373 ps3av.av_hw_conf.num_of_avmulti; 402 ps3av->av_hw_conf.num_of_avmulti;
374 num_of_opt_port = ps3av.av_hw_conf.num_of_spdif; 403 num_of_opt_port = ps3av->av_hw_conf.num_of_spdif;
375 404
376 for (i = 0; i < num_of_av_port; i++) { 405 for (i = 0; i < num_of_av_port; i++) {
377 res = ps3av_cmd_av_audio_mute(1, &ps3av.av_port[i], mute); 406 res = ps3av_cmd_av_audio_mute(1, &ps3av->av_port[i], mute);
378 if (res < 0) 407 if (res < 0)
379 return -1; 408 return -1;
380 } 409 }
381 for (i = 0; i < num_of_opt_port; i++) { 410 for (i = 0; i < num_of_opt_port; i++) {
382 res = ps3av_cmd_audio_mute(1, &ps3av.opt_port[i], mute); 411 res = ps3av_cmd_audio_mute(1, &ps3av->opt_port[i], mute);
383 if (res < 0) 412 if (res < 0)
384 return -1; 413 return -1;
385 } 414 }
@@ -394,40 +423,40 @@ int ps3av_set_audio_mode(u32 ch, u32 fs, u32 word_bits, u32 format, u32 source)
394 struct ps3av_pkt_audio_mode audio_mode; 423 struct ps3av_pkt_audio_mode audio_mode;
395 u32 len = 0; 424 u32 len = 0;
396 425
397 num_of_audio = ps3av.av_hw_conf.num_of_hdmi + 426 num_of_audio = ps3av->av_hw_conf.num_of_hdmi +
398 ps3av.av_hw_conf.num_of_avmulti + 427 ps3av->av_hw_conf.num_of_avmulti +
399 ps3av.av_hw_conf.num_of_spdif; 428 ps3av->av_hw_conf.num_of_spdif;
400 429
401 avb_param.num_of_video_pkt = 0; 430 avb_param.num_of_video_pkt = 0;
402 avb_param.num_of_audio_pkt = PS3AV_AVB_NUM_AUDIO; /* always 0 */ 431 avb_param.num_of_audio_pkt = PS3AV_AVB_NUM_AUDIO; /* always 0 */
403 avb_param.num_of_av_video_pkt = 0; 432 avb_param.num_of_av_video_pkt = 0;
404 avb_param.num_of_av_audio_pkt = ps3av.av_hw_conf.num_of_hdmi; 433 avb_param.num_of_av_audio_pkt = ps3av->av_hw_conf.num_of_hdmi;
405 434
406 vid = video_mode_table[ps3av.ps3av_mode].vid; 435 vid = video_mode_table[ps3av->ps3av_mode].vid;
407 436
408 /* audio mute */ 437 /* audio mute */
409 ps3av_set_audio_mute(PS3AV_CMD_MUTE_ON); 438 ps3av_set_audio_mute(PS3AV_CMD_MUTE_ON);
410 439
411 /* audio inactive */ 440 /* audio inactive */
412 res = ps3av_cmd_audio_active(0, ps3av.audio_port); 441 res = ps3av_cmd_audio_active(0, ps3av->audio_port);
413 if (res < 0) 442 if (res < 0)
414 dev_dbg(&ps3av_dev.core, 443 dev_dbg(&ps3av->dev->core,
415 "ps3av_cmd_audio_active OFF failed\n"); 444 "ps3av_cmd_audio_active OFF failed\n");
416 445
417 /* audio_pkt */ 446 /* audio_pkt */
418 for (i = 0; i < num_of_audio; i++) { 447 for (i = 0; i < num_of_audio; i++) {
419 ps3av_cmd_set_audio_mode(&audio_mode, ps3av.av_port[i], ch, fs, 448 ps3av_cmd_set_audio_mode(&audio_mode, ps3av->av_port[i], ch,
420 word_bits, format, source); 449 fs, word_bits, format, source);
421 if (i < ps3av.av_hw_conf.num_of_hdmi) { 450 if (i < ps3av->av_hw_conf.num_of_hdmi) {
422 /* hdmi only */ 451 /* hdmi only */
423 len += ps3av_cmd_set_av_audio_param(&avb_param.buf[len], 452 len += ps3av_cmd_set_av_audio_param(&avb_param.buf[len],
424 ps3av.av_port[i], 453 ps3av->av_port[i],
425 &audio_mode, vid); 454 &audio_mode, vid);
426 } 455 }
427 /* audio_mode pkt should be sent separately */ 456 /* audio_mode pkt should be sent separately */
428 res = ps3av_cmd_audio_mode(&audio_mode); 457 res = ps3av_cmd_audio_mode(&audio_mode);
429 if (res < 0) 458 if (res < 0)
430 dev_dbg(&ps3av_dev.core, 459 dev_dbg(&ps3av->dev->core,
431 "ps3av_cmd_audio_mode failed, port:%x\n", i); 460 "ps3av_cmd_audio_mode failed, port:%x\n", i);
432 } 461 }
433 462
@@ -435,15 +464,16 @@ int ps3av_set_audio_mode(u32 ch, u32 fs, u32 word_bits, u32 format, u32 source)
435 len += offsetof(struct ps3av_pkt_avb_param, buf); 464 len += offsetof(struct ps3av_pkt_avb_param, buf);
436 res = ps3av_cmd_avb_param(&avb_param, len); 465 res = ps3av_cmd_avb_param(&avb_param, len);
437 if (res < 0) 466 if (res < 0)
438 dev_dbg(&ps3av_dev.core, "ps3av_cmd_avb_param failed\n"); 467 dev_dbg(&ps3av->dev->core, "ps3av_cmd_avb_param failed\n");
439 468
440 /* audio mute */ 469 /* audio mute */
441 ps3av_set_audio_mute(PS3AV_CMD_MUTE_OFF); 470 ps3av_set_audio_mute(PS3AV_CMD_MUTE_OFF);
442 471
443 /* audio active */ 472 /* audio active */
444 res = ps3av_cmd_audio_active(1, ps3av.audio_port); 473 res = ps3av_cmd_audio_active(1, ps3av->audio_port);
445 if (res < 0) 474 if (res < 0)
446 dev_dbg(&ps3av_dev.core, "ps3av_cmd_audio_active ON failed\n"); 475 dev_dbg(&ps3av->dev->core,
476 "ps3av_cmd_audio_active ON failed\n");
447 477
448 return 0; 478 return 0;
449} 479}
@@ -456,7 +486,7 @@ static int ps3av_set_videomode(void)
456 ps3av_set_av_video_mute(PS3AV_CMD_MUTE_ON); 486 ps3av_set_av_video_mute(PS3AV_CMD_MUTE_ON);
457 487
458 /* wake up ps3avd to do the actual video mode setting */ 488 /* wake up ps3avd to do the actual video mode setting */
459 queue_work(ps3av.wq, &ps3av.work); 489 queue_work(ps3av->wq, &ps3av->work);
460 490
461 return 0; 491 return 0;
462} 492}
@@ -473,8 +503,8 @@ static void ps3av_set_videomode_cont(u32 id, u32 old_id)
473 503
474 avb_param.num_of_video_pkt = PS3AV_AVB_NUM_VIDEO; /* num of head */ 504 avb_param.num_of_video_pkt = PS3AV_AVB_NUM_VIDEO; /* num of head */
475 avb_param.num_of_audio_pkt = 0; 505 avb_param.num_of_audio_pkt = 0;
476 avb_param.num_of_av_video_pkt = ps3av.av_hw_conf.num_of_hdmi + 506 avb_param.num_of_av_video_pkt = ps3av->av_hw_conf.num_of_hdmi +
477 ps3av.av_hw_conf.num_of_avmulti; 507 ps3av->av_hw_conf.num_of_avmulti;
478 avb_param.num_of_av_audio_pkt = 0; 508 avb_param.num_of_av_audio_pkt = 0;
479 509
480 /* video signal off */ 510 /* video signal off */
@@ -484,21 +514,21 @@ static void ps3av_set_videomode_cont(u32 id, u32 old_id)
484 if (id & PS3AV_MODE_HDCP_OFF) { 514 if (id & PS3AV_MODE_HDCP_OFF) {
485 res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_HDCP_OFF); 515 res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_HDCP_OFF);
486 if (res == PS3AV_STATUS_UNSUPPORTED_HDMI_MODE) 516 if (res == PS3AV_STATUS_UNSUPPORTED_HDMI_MODE)
487 dev_dbg(&ps3av_dev.core, "Not supported\n"); 517 dev_dbg(&ps3av->dev->core, "Not supported\n");
488 else if (res) 518 else if (res)
489 dev_dbg(&ps3av_dev.core, 519 dev_dbg(&ps3av->dev->core,
490 "ps3av_cmd_av_hdmi_mode failed\n"); 520 "ps3av_cmd_av_hdmi_mode failed\n");
491 } else if (old_id & PS3AV_MODE_HDCP_OFF) { 521 } else if (old_id & PS3AV_MODE_HDCP_OFF) {
492 res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_MODE_NORMAL); 522 res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_MODE_NORMAL);
493 if (res < 0 && res != PS3AV_STATUS_UNSUPPORTED_HDMI_MODE) 523 if (res < 0 && res != PS3AV_STATUS_UNSUPPORTED_HDMI_MODE)
494 dev_dbg(&ps3av_dev.core, 524 dev_dbg(&ps3av->dev->core,
495 "ps3av_cmd_av_hdmi_mode failed\n"); 525 "ps3av_cmd_av_hdmi_mode failed\n");
496 } 526 }
497 527
498 /* video_pkt */ 528 /* video_pkt */
499 for (i = 0; i < avb_param.num_of_video_pkt; i++) 529 for (i = 0; i < avb_param.num_of_video_pkt; i++)
500 len += ps3av_cmd_set_video_mode(&avb_param.buf[len], 530 len += ps3av_cmd_set_video_mode(&avb_param.buf[len],
501 ps3av.head[i], video_mode->vid, 531 ps3av->head[i], video_mode->vid,
502 video_mode->fmt, id); 532 video_mode->fmt, id);
503 /* av_video_pkt */ 533 /* av_video_pkt */
504 for (i = 0; i < avb_param.num_of_av_video_pkt; i++) { 534 for (i = 0; i < avb_param.num_of_av_video_pkt; i++) {
@@ -507,12 +537,12 @@ static void ps3av_set_videomode_cont(u32 id, u32 old_id)
507 else 537 else
508 av_video_cs = video_mode->cs; 538 av_video_cs = video_mode->cs;
509#ifndef PS3AV_HDMI_YUV 539#ifndef PS3AV_HDMI_YUV
510 if (ps3av.av_port[i] == PS3AV_CMD_AVPORT_HDMI_0 || 540 if (ps3av->av_port[i] == PS3AV_CMD_AVPORT_HDMI_0 ||
511 ps3av.av_port[i] == PS3AV_CMD_AVPORT_HDMI_1) 541 ps3av->av_port[i] == PS3AV_CMD_AVPORT_HDMI_1)
512 av_video_cs = RGB8; /* use RGB for HDMI */ 542 av_video_cs = RGB8; /* use RGB for HDMI */
513#endif 543#endif
514 len += ps3av_cmd_set_av_video_cs(&avb_param.buf[len], 544 len += ps3av_cmd_set_av_video_cs(&avb_param.buf[len],
515 ps3av.av_port[i], 545 ps3av->av_port[i],
516 video_mode->vid, av_video_cs, 546 video_mode->vid, av_video_cs,
517 video_mode->aspect, id); 547 video_mode->aspect, id);
518 } 548 }
@@ -524,7 +554,7 @@ static void ps3av_set_videomode_cont(u32 id, u32 old_id)
524 "%s: Command failed. Please try your request again. \n", 554 "%s: Command failed. Please try your request again. \n",
525 __func__); 555 __func__);
526 else if (res) 556 else if (res)
527 dev_dbg(&ps3av_dev.core, "ps3av_cmd_avb_param failed\n"); 557 dev_dbg(&ps3av->dev->core, "ps3av_cmd_avb_param failed\n");
528 558
529 msleep(1500); 559 msleep(1500);
530 /* av video mute */ 560 /* av video mute */
@@ -533,8 +563,8 @@ static void ps3av_set_videomode_cont(u32 id, u32 old_id)
533 563
534static void ps3avd(struct work_struct *work) 564static void ps3avd(struct work_struct *work)
535{ 565{
536 ps3av_set_videomode_cont(ps3av.ps3av_mode, ps3av.ps3av_mode_old); 566 ps3av_set_videomode_cont(ps3av->ps3av_mode, ps3av->ps3av_mode_old);
537 complete(&ps3av.done); 567 complete(&ps3av->done);
538} 568}
539 569
540static int ps3av_vid2table_id(int vid) 570static int ps3av_vid2table_id(int vid)
@@ -601,7 +631,7 @@ static int ps3av_hdmi_get_vid(struct ps3av_info_monitor *info)
601 return vid; 631 return vid;
602 } 632 }
603 633
604 if (ps3av.region & PS3AV_REGION_60) 634 if (ps3av->region & PS3AV_REGION_60)
605 vid = PS3AV_DEFAULT_HDMI_VID_REG_60; 635 vid = PS3AV_DEFAULT_HDMI_VID_REG_60;
606 else 636 else
607 vid = PS3AV_DEFAULT_HDMI_VID_REG_50; 637 vid = PS3AV_DEFAULT_HDMI_VID_REG_50;
@@ -643,16 +673,16 @@ static int ps3av_auto_videomode(struct ps3av_pkt_av_get_hw_conf *av_hw_conf,
643 vid = PS3AV_DEFAULT_DVI_VID; 673 vid = PS3AV_DEFAULT_DVI_VID;
644 } else if (vid == -1) { 674 } else if (vid == -1) {
645 /* no HDMI interface or HDMI is off */ 675 /* no HDMI interface or HDMI is off */
646 if (ps3av.region & PS3AV_REGION_60) 676 if (ps3av->region & PS3AV_REGION_60)
647 vid = PS3AV_DEFAULT_AVMULTI_VID_REG_60; 677 vid = PS3AV_DEFAULT_AVMULTI_VID_REG_60;
648 else 678 else
649 vid = PS3AV_DEFAULT_AVMULTI_VID_REG_50; 679 vid = PS3AV_DEFAULT_AVMULTI_VID_REG_50;
650 if (ps3av.region & PS3AV_REGION_RGB) 680 if (ps3av->region & PS3AV_REGION_RGB)
651 rgb = PS3AV_MODE_RGB; 681 rgb = PS3AV_MODE_RGB;
652 } else if (boot) { 682 } else if (boot) {
653 /* HDMI: using DEFAULT HDMI_VID while booting up */ 683 /* HDMI: using DEFAULT HDMI_VID while booting up */
654 info = &monitor_info.info; 684 info = &monitor_info.info;
655 if (ps3av.region & PS3AV_REGION_60) { 685 if (ps3av->region & PS3AV_REGION_60) {
656 if (info->res_60.res_bits & PS3AV_RESBIT_720x480P) 686 if (info->res_60.res_bits & PS3AV_RESBIT_720x480P)
657 vid = PS3AV_DEFAULT_HDMI_VID_REG_60; 687 vid = PS3AV_DEFAULT_HDMI_VID_REG_60;
658 else if (info->res_50.res_bits & PS3AV_RESBIT_720x576P) 688 else if (info->res_50.res_bits & PS3AV_RESBIT_720x576P)
@@ -715,14 +745,14 @@ int ps3av_set_video_mode(u32 id, int boot)
715 745
716 size = ARRAY_SIZE(video_mode_table); 746 size = ARRAY_SIZE(video_mode_table);
717 if ((id & PS3AV_MODE_MASK) > size - 1 || id < 0) { 747 if ((id & PS3AV_MODE_MASK) > size - 1 || id < 0) {
718 dev_dbg(&ps3av_dev.core, "%s: error id :%d\n", __func__, id); 748 dev_dbg(&ps3av->dev->core, "%s: error id :%d\n", __func__, id);
719 return -EINVAL; 749 return -EINVAL;
720 } 750 }
721 751
722 /* auto mode */ 752 /* auto mode */
723 option = id & ~PS3AV_MODE_MASK; 753 option = id & ~PS3AV_MODE_MASK;
724 if ((id & PS3AV_MODE_MASK) == 0) { 754 if ((id & PS3AV_MODE_MASK) == 0) {
725 id = ps3av_auto_videomode(&ps3av.av_hw_conf, boot); 755 id = ps3av_auto_videomode(&ps3av->av_hw_conf, boot);
726 if (id < 1) { 756 if (id < 1) {
727 printk(KERN_ERR "%s: invalid id :%d\n", __func__, id); 757 printk(KERN_ERR "%s: invalid id :%d\n", __func__, id);
728 return -EINVAL; 758 return -EINVAL;
@@ -731,11 +761,11 @@ int ps3av_set_video_mode(u32 id, int boot)
731 } 761 }
732 762
733 /* set videomode */ 763 /* set videomode */
734 wait_for_completion(&ps3av.done); 764 wait_for_completion(&ps3av->done);
735 ps3av.ps3av_mode_old = ps3av.ps3av_mode; 765 ps3av->ps3av_mode_old = ps3av->ps3av_mode;
736 ps3av.ps3av_mode = id; 766 ps3av->ps3av_mode = id;
737 if (ps3av_set_videomode()) 767 if (ps3av_set_videomode())
738 ps3av.ps3av_mode = ps3av.ps3av_mode_old; 768 ps3av->ps3av_mode = ps3av->ps3av_mode_old;
739 769
740 return 0; 770 return 0;
741} 771}
@@ -744,7 +774,7 @@ EXPORT_SYMBOL_GPL(ps3av_set_video_mode);
744 774
745int ps3av_get_auto_mode(int boot) 775int ps3av_get_auto_mode(int boot)
746{ 776{
747 return ps3av_auto_videomode(&ps3av.av_hw_conf, boot); 777 return ps3av_auto_videomode(&ps3av->av_hw_conf, boot);
748} 778}
749 779
750EXPORT_SYMBOL_GPL(ps3av_get_auto_mode); 780EXPORT_SYMBOL_GPL(ps3av_get_auto_mode);
@@ -772,7 +802,7 @@ EXPORT_SYMBOL_GPL(ps3av_set_mode);
772 802
773int ps3av_get_mode(void) 803int ps3av_get_mode(void)
774{ 804{
775 return ps3av.ps3av_mode; 805 return ps3av ? ps3av->ps3av_mode : 0;
776} 806}
777 807
778EXPORT_SYMBOL_GPL(ps3av_get_mode); 808EXPORT_SYMBOL_GPL(ps3av_get_mode);
@@ -842,82 +872,65 @@ int ps3av_audio_mute(int mute)
842 872
843EXPORT_SYMBOL_GPL(ps3av_audio_mute); 873EXPORT_SYMBOL_GPL(ps3av_audio_mute);
844 874
845int ps3av_dev_open(void) 875void ps3av_register_flip_ctl(void (*flip_ctl)(int on, void *data),
876 void *flip_data)
846{ 877{
847 int status = 0; 878 mutex_lock(&ps3av->mutex);
848 879 ps3av->flip_ctl = flip_ctl;
849 mutex_lock(&ps3av.mutex); 880 ps3av->flip_data = flip_data;
850 if (!ps3av.open_count++) { 881 mutex_unlock(&ps3av->mutex);
851 status = lv1_gpu_open(0);
852 if (status) {
853 printk(KERN_ERR "%s: lv1_gpu_open failed %d\n",
854 __func__, status);
855 ps3av.open_count--;
856 }
857 }
858 mutex_unlock(&ps3av.mutex);
859
860 return status;
861} 882}
883EXPORT_SYMBOL_GPL(ps3av_register_flip_ctl);
862 884
863EXPORT_SYMBOL_GPL(ps3av_dev_open); 885void ps3av_flip_ctl(int on)
864
865int ps3av_dev_close(void)
866{ 886{
867 int status = 0; 887 mutex_lock(&ps3av->mutex);
868 888 if (ps3av->flip_ctl)
869 mutex_lock(&ps3av.mutex); 889 ps3av->flip_ctl(on, ps3av->flip_data);
870 if (ps3av.open_count <= 0) { 890 mutex_unlock(&ps3av->mutex);
871 printk(KERN_ERR "%s: GPU already closed\n", __func__);
872 status = -1;
873 } else if (!--ps3av.open_count) {
874 status = lv1_gpu_close();
875 if (status)
876 printk(KERN_WARNING "%s: lv1_gpu_close failed %d\n",
877 __func__, status);
878 }
879 mutex_unlock(&ps3av.mutex);
880
881 return status;
882} 891}
883 892
884EXPORT_SYMBOL_GPL(ps3av_dev_close); 893static int ps3av_probe(struct ps3_system_bus_device *dev)
885
886static int ps3av_probe(struct ps3_vuart_port_device *dev)
887{ 894{
888 int res; 895 int res;
889 u32 id; 896 u32 id;
890 897
891 dev_dbg(&ps3av_dev.core, "init ...\n"); 898 dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
892 dev_dbg(&ps3av_dev.core, " timeout=%d\n", timeout); 899 dev_dbg(&dev->core, " timeout=%d\n", timeout);
893 900
894 memset(&ps3av, 0, sizeof(ps3av)); 901 if (ps3av) {
895 902 dev_err(&dev->core, "Only one ps3av device is supported\n");
896 mutex_init(&ps3av.mutex); 903 return -EBUSY;
897 ps3av.ps3av_mode = 0; 904 }
898 ps3av.dev = dev;
899 905
900 INIT_WORK(&ps3av.work, ps3avd); 906 ps3av = kzalloc(sizeof(*ps3av), GFP_KERNEL);
901 init_completion(&ps3av.done); 907 if (!ps3av)
902 complete(&ps3av.done);
903 ps3av.wq = create_singlethread_workqueue("ps3avd");
904 if (!ps3av.wq)
905 return -ENOMEM; 908 return -ENOMEM;
906 909
907 ps3av.available = 1; 910 mutex_init(&ps3av->mutex);
911 ps3av->ps3av_mode = 0;
912 ps3av->dev = dev;
913
914 INIT_WORK(&ps3av->work, ps3avd);
915 init_completion(&ps3av->done);
916 complete(&ps3av->done);
917 ps3av->wq = create_singlethread_workqueue("ps3avd");
918 if (!ps3av->wq)
919 goto fail;
920
908 switch (ps3_os_area_get_av_multi_out()) { 921 switch (ps3_os_area_get_av_multi_out()) {
909 case PS3_PARAM_AV_MULTI_OUT_NTSC: 922 case PS3_PARAM_AV_MULTI_OUT_NTSC:
910 ps3av.region = PS3AV_REGION_60; 923 ps3av->region = PS3AV_REGION_60;
911 break; 924 break;
912 case PS3_PARAM_AV_MULTI_OUT_PAL_YCBCR: 925 case PS3_PARAM_AV_MULTI_OUT_PAL_YCBCR:
913 case PS3_PARAM_AV_MULTI_OUT_SECAM: 926 case PS3_PARAM_AV_MULTI_OUT_SECAM:
914 ps3av.region = PS3AV_REGION_50; 927 ps3av->region = PS3AV_REGION_50;
915 break; 928 break;
916 case PS3_PARAM_AV_MULTI_OUT_PAL_RGB: 929 case PS3_PARAM_AV_MULTI_OUT_PAL_RGB:
917 ps3av.region = PS3AV_REGION_50 | PS3AV_REGION_RGB; 930 ps3av->region = PS3AV_REGION_50 | PS3AV_REGION_RGB;
918 break; 931 break;
919 default: 932 default:
920 ps3av.region = PS3AV_REGION_60; 933 ps3av->region = PS3AV_REGION_60;
921 break; 934 break;
922 } 935 }
923 936
@@ -927,39 +940,47 @@ static int ps3av_probe(struct ps3_vuart_port_device *dev)
927 printk(KERN_ERR "%s: ps3av_cmd_init failed %d\n", __func__, 940 printk(KERN_ERR "%s: ps3av_cmd_init failed %d\n", __func__,
928 res); 941 res);
929 942
930 ps3av_get_hw_conf(&ps3av); 943 ps3av_get_hw_conf(ps3av);
931 id = ps3av_auto_videomode(&ps3av.av_hw_conf, 1); 944 id = ps3av_auto_videomode(&ps3av->av_hw_conf, 1);
932 mutex_lock(&ps3av.mutex); 945 mutex_lock(&ps3av->mutex);
933 ps3av.ps3av_mode = id; 946 ps3av->ps3av_mode = id;
934 mutex_unlock(&ps3av.mutex); 947 mutex_unlock(&ps3av->mutex);
935 948
936 dev_dbg(&ps3av_dev.core, "init...done\n"); 949 dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
937 950
938 return 0; 951 return 0;
952
953fail:
954 kfree(ps3av);
955 ps3av = NULL;
956 return -ENOMEM;
939} 957}
940 958
941static int ps3av_remove(struct ps3_vuart_port_device *dev) 959static int ps3av_remove(struct ps3_system_bus_device *dev)
942{ 960{
943 if (ps3av.available) { 961 dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
962 if (ps3av) {
944 ps3av_cmd_fin(); 963 ps3av_cmd_fin();
945 if (ps3av.wq) 964 if (ps3av->wq)
946 destroy_workqueue(ps3av.wq); 965 destroy_workqueue(ps3av->wq);
947 ps3av.available = 0; 966 kfree(ps3av);
967 ps3av = NULL;
948 } 968 }
949 969
970 dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
950 return 0; 971 return 0;
951} 972}
952 973
953static void ps3av_shutdown(struct ps3_vuart_port_device *dev) 974static void ps3av_shutdown(struct ps3_system_bus_device *dev)
954{ 975{
976 dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
955 ps3av_remove(dev); 977 ps3av_remove(dev);
978 dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
956} 979}
957 980
958static struct ps3_vuart_port_driver ps3av_driver = { 981static struct ps3_vuart_port_driver ps3av_driver = {
959 .match_id = PS3_MATCH_ID_AV_SETTINGS, 982 .core.match_id = PS3_MATCH_ID_AV_SETTINGS,
960 .core = { 983 .core.core.name = "ps3_av",
961 .name = "ps3_av",
962 },
963 .probe = ps3av_probe, 984 .probe = ps3av_probe,
964 .remove = ps3av_remove, 985 .remove = ps3av_remove,
965 .shutdown = ps3av_shutdown, 986 .shutdown = ps3av_shutdown,
@@ -972,6 +993,8 @@ static int ps3av_module_init(void)
972 if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) 993 if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
973 return -ENODEV; 994 return -ENODEV;
974 995
996 pr_debug(" -> %s:%d\n", __func__, __LINE__);
997
975 error = ps3_vuart_port_driver_register(&ps3av_driver); 998 error = ps3_vuart_port_driver_register(&ps3av_driver);
976 if (error) { 999 if (error) {
977 printk(KERN_ERR 1000 printk(KERN_ERR
@@ -980,20 +1003,21 @@ static int ps3av_module_init(void)
980 return error; 1003 return error;
981 } 1004 }
982 1005
983 error = ps3_vuart_port_device_register(&ps3av_dev); 1006 pr_debug(" <- %s:%d\n", __func__, __LINE__);
984 if (error)
985 printk(KERN_ERR
986 "%s: ps3_vuart_port_device_register failed %d\n",
987 __func__, error);
988
989 return error; 1007 return error;
990} 1008}
991 1009
992static void __exit ps3av_module_exit(void) 1010static void __exit ps3av_module_exit(void)
993{ 1011{
994 device_unregister(&ps3av_dev.core); 1012 pr_debug(" -> %s:%d\n", __func__, __LINE__);
995 ps3_vuart_port_driver_unregister(&ps3av_driver); 1013 ps3_vuart_port_driver_unregister(&ps3av_driver);
1014 pr_debug(" <- %s:%d\n", __func__, __LINE__);
996} 1015}
997 1016
998subsys_initcall(ps3av_module_init); 1017subsys_initcall(ps3av_module_init);
999module_exit(ps3av_module_exit); 1018module_exit(ps3av_module_exit);
1019
1020MODULE_LICENSE("GPL v2");
1021MODULE_DESCRIPTION("PS3 AV Settings Driver");
1022MODULE_AUTHOR("Sony Computer Entertainment Inc.");
1023MODULE_ALIAS(PS3_MODULE_ALIAS_AV_SETTINGS);