diff options
| -rw-r--r-- | drivers/video/via/hw.c | 53 | ||||
| -rw-r--r-- | drivers/video/via/hw.h | 10 | ||||
| -rw-r--r-- | drivers/video/via/viafbdev.c | 175 | ||||
| -rw-r--r-- | drivers/video/via/viafbdev.h | 2 |
4 files changed, 216 insertions, 24 deletions
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index 03303232e543..e65edcea46eb 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c | |||
| @@ -718,6 +718,16 @@ static struct rgbLUT palLUT_table[] = { | |||
| 718 | 0x00} | 718 | 0x00} |
| 719 | }; | 719 | }; |
| 720 | 720 | ||
| 721 | static struct via_device_mapping device_mapping[] = { | ||
| 722 | {VIA_6C, "6C"}, | ||
| 723 | {VIA_93, "93"}, | ||
| 724 | {VIA_96, "96"}, | ||
| 725 | {VIA_CRT, "CRT"}, | ||
| 726 | {VIA_DVP1, "DVP1"}, | ||
| 727 | {VIA_LVDS1, "LVDS1"}, | ||
| 728 | {VIA_LVDS2, "LVDS2"} | ||
| 729 | }; | ||
| 730 | |||
| 721 | static void load_fix_bit_crtc_reg(void); | 731 | static void load_fix_bit_crtc_reg(void); |
| 722 | static void __devinit init_gfx_chip_info(int chip_type); | 732 | static void __devinit init_gfx_chip_info(int chip_type); |
| 723 | static void __devinit init_tmds_chip_info(void); | 733 | static void __devinit init_tmds_chip_info(void); |
| @@ -1026,6 +1036,49 @@ void via_set_source(u32 devices, u8 iga) | |||
| 1026 | set_lvds2_source(iga); | 1036 | set_lvds2_source(iga); |
| 1027 | } | 1037 | } |
| 1028 | 1038 | ||
| 1039 | u32 via_parse_odev(char *input, char **end) | ||
| 1040 | { | ||
| 1041 | char *ptr = input; | ||
| 1042 | u32 odev = 0; | ||
| 1043 | bool next = true; | ||
| 1044 | int i, len; | ||
| 1045 | |||
| 1046 | while (next) { | ||
| 1047 | next = false; | ||
| 1048 | for (i = 0; i < ARRAY_SIZE(device_mapping); i++) { | ||
| 1049 | len = strlen(device_mapping[i].name); | ||
| 1050 | if (!strncmp(ptr, device_mapping[i].name, len)) { | ||
| 1051 | odev |= device_mapping[i].device; | ||
| 1052 | ptr += len; | ||
| 1053 | if (*ptr == ',') { | ||
| 1054 | ptr++; | ||
| 1055 | next = true; | ||
| 1056 | } | ||
| 1057 | } | ||
| 1058 | } | ||
| 1059 | } | ||
| 1060 | |||
| 1061 | *end = ptr; | ||
| 1062 | return odev; | ||
| 1063 | } | ||
| 1064 | |||
| 1065 | void via_odev_to_seq(struct seq_file *m, u32 odev) | ||
| 1066 | { | ||
| 1067 | int i, count = 0; | ||
| 1068 | |||
| 1069 | for (i = 0; i < ARRAY_SIZE(device_mapping); i++) { | ||
| 1070 | if (odev & device_mapping[i].device) { | ||
| 1071 | if (count > 0) | ||
| 1072 | seq_putc(m, ','); | ||
| 1073 | |||
| 1074 | seq_puts(m, device_mapping[i].name); | ||
| 1075 | count++; | ||
| 1076 | } | ||
| 1077 | } | ||
| 1078 | |||
| 1079 | seq_putc(m, '\n'); | ||
| 1080 | } | ||
| 1081 | |||
| 1029 | static void load_fix_bit_crtc_reg(void) | 1082 | static void load_fix_bit_crtc_reg(void) |
| 1030 | { | 1083 | { |
| 1031 | /* always set to 1 */ | 1084 | /* always set to 1 */ |
diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h index 45dee39a8b23..657dbd64a089 100644 --- a/drivers/video/via/hw.h +++ b/drivers/video/via/hw.h | |||
| @@ -22,6 +22,8 @@ | |||
| 22 | #ifndef __HW_H__ | 22 | #ifndef __HW_H__ |
| 23 | #define __HW_H__ | 23 | #define __HW_H__ |
| 24 | 24 | ||
| 25 | #include <linux/seq_file.h> | ||
| 26 | |||
| 25 | #include "viamode.h" | 27 | #include "viamode.h" |
| 26 | #include "global.h" | 28 | #include "global.h" |
| 27 | #include "via_modesetting.h" | 29 | #include "via_modesetting.h" |
| @@ -882,6 +884,11 @@ struct pci_device_id_info { | |||
| 882 | u32 chip_index; | 884 | u32 chip_index; |
| 883 | }; | 885 | }; |
| 884 | 886 | ||
| 887 | struct via_device_mapping { | ||
| 888 | u32 device; | ||
| 889 | const char *name; | ||
| 890 | }; | ||
| 891 | |||
| 885 | extern unsigned int viafb_second_virtual_xres; | 892 | extern unsigned int viafb_second_virtual_xres; |
| 886 | extern int viafb_SAMM_ON; | 893 | extern int viafb_SAMM_ON; |
| 887 | extern int viafb_dual_fb; | 894 | extern int viafb_dual_fb; |
| @@ -899,6 +906,9 @@ void viafb_load_reg(int timing_value, int viafb_load_reg_num, | |||
| 899 | int io_type); | 906 | int io_type); |
| 900 | void viafb_crt_disable(void); | 907 | void viafb_crt_disable(void); |
| 901 | void viafb_crt_enable(void); | 908 | void viafb_crt_enable(void); |
| 909 | void via_set_source(u32 devices, u8 iga); | ||
| 910 | u32 via_parse_odev(char *input, char **end); | ||
| 911 | void via_odev_to_seq(struct seq_file *m, u32 odev); | ||
| 902 | void init_ad9389(void); | 912 | void init_ad9389(void); |
| 903 | /* Access I/O Function */ | 913 | /* Access I/O Function */ |
| 904 | void viafb_lock_crt(void); | 914 | void viafb_lock_crt(void); |
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index 5a947b096269..80ce43a318bb 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c | |||
| @@ -1431,38 +1431,169 @@ static const struct file_operations viafb_vt1636_proc_fops = { | |||
| 1431 | .write = viafb_vt1636_proc_write, | 1431 | .write = viafb_vt1636_proc_write, |
| 1432 | }; | 1432 | }; |
| 1433 | 1433 | ||
| 1434 | static void viafb_init_proc(struct proc_dir_entry **viafb_entry) | 1434 | #endif /* CONFIG_FB_VIA_DIRECT_PROCFS */ |
| 1435 | |||
| 1436 | static ssize_t odev_update(const char __user *buffer, size_t count, u32 *odev) | ||
| 1435 | { | 1437 | { |
| 1436 | *viafb_entry = proc_mkdir("viafb", NULL); | 1438 | char buf[64], *ptr = buf; |
| 1437 | if (*viafb_entry) { | 1439 | u32 devices; |
| 1438 | proc_create("dvp0", 0, *viafb_entry, &viafb_dvp0_proc_fops); | 1440 | bool add, sub; |
| 1439 | proc_create("dvp1", 0, *viafb_entry, &viafb_dvp1_proc_fops); | 1441 | |
| 1440 | proc_create("dfph", 0, *viafb_entry, &viafb_dfph_proc_fops); | 1442 | if (count < 1 || count > 63) |
| 1441 | proc_create("dfpl", 0, *viafb_entry, &viafb_dfpl_proc_fops); | 1443 | return -EINVAL; |
| 1442 | if (VT1636_LVDS == viaparinfo->chip_info->lvds_chip_info. | 1444 | if (copy_from_user(&buf[0], buffer, count)) |
| 1443 | lvds_chip_name || VT1636_LVDS == | 1445 | return -EFAULT; |
| 1444 | viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) { | 1446 | buf[count] = '\0'; |
| 1445 | proc_create("vt1636", 0, *viafb_entry, &viafb_vt1636_proc_fops); | 1447 | add = buf[0] == '+'; |
| 1446 | } | 1448 | sub = buf[0] == '-'; |
| 1449 | if (add || sub) | ||
| 1450 | ptr++; | ||
| 1451 | devices = via_parse_odev(ptr, &ptr); | ||
| 1452 | if (*ptr == '\n') | ||
| 1453 | ptr++; | ||
| 1454 | if (*ptr != 0) | ||
| 1455 | return -EINVAL; | ||
| 1456 | if (add) | ||
| 1457 | *odev |= devices; | ||
| 1458 | else if (sub) | ||
| 1459 | *odev &= ~devices; | ||
| 1460 | else | ||
| 1461 | *odev = devices; | ||
| 1462 | return count; | ||
| 1463 | } | ||
| 1464 | |||
| 1465 | static int viafb_iga1_odev_proc_show(struct seq_file *m, void *v) | ||
| 1466 | { | ||
| 1467 | via_odev_to_seq(m, viaparinfo->shared->iga1_devices); | ||
| 1468 | return 0; | ||
| 1469 | } | ||
| 1470 | |||
| 1471 | static int viafb_iga1_odev_proc_open(struct inode *inode, struct file *file) | ||
| 1472 | { | ||
| 1473 | return single_open(file, viafb_iga1_odev_proc_show, NULL); | ||
| 1474 | } | ||
| 1475 | |||
| 1476 | static ssize_t viafb_iga1_odev_proc_write(struct file *file, | ||
| 1477 | const char __user *buffer, size_t count, loff_t *pos) | ||
| 1478 | { | ||
| 1479 | u32 dev_on, dev_off, dev_old, dev_new; | ||
| 1480 | ssize_t res; | ||
| 1481 | |||
| 1482 | dev_old = dev_new = viaparinfo->shared->iga1_devices; | ||
| 1483 | res = odev_update(buffer, count, &dev_new); | ||
| 1484 | if (res != count) | ||
| 1485 | return res; | ||
| 1486 | dev_off = dev_old & ~dev_new; | ||
| 1487 | dev_on = dev_new & ~dev_old; | ||
| 1488 | viaparinfo->shared->iga1_devices = dev_new; | ||
| 1489 | viaparinfo->shared->iga2_devices &= ~dev_new; | ||
| 1490 | via_set_source(dev_new, IGA1); | ||
| 1491 | return res; | ||
| 1492 | } | ||
| 1493 | |||
| 1494 | static const struct file_operations viafb_iga1_odev_proc_fops = { | ||
| 1495 | .owner = THIS_MODULE, | ||
| 1496 | .open = viafb_iga1_odev_proc_open, | ||
| 1497 | .read = seq_read, | ||
| 1498 | .llseek = seq_lseek, | ||
| 1499 | .release = single_release, | ||
| 1500 | .write = viafb_iga1_odev_proc_write, | ||
| 1501 | }; | ||
| 1502 | |||
| 1503 | static int viafb_iga2_odev_proc_show(struct seq_file *m, void *v) | ||
| 1504 | { | ||
| 1505 | via_odev_to_seq(m, viaparinfo->shared->iga2_devices); | ||
| 1506 | return 0; | ||
| 1507 | } | ||
| 1508 | |||
| 1509 | static int viafb_iga2_odev_proc_open(struct inode *inode, struct file *file) | ||
| 1510 | { | ||
| 1511 | return single_open(file, viafb_iga2_odev_proc_show, NULL); | ||
| 1512 | } | ||
| 1513 | |||
| 1514 | static ssize_t viafb_iga2_odev_proc_write(struct file *file, | ||
| 1515 | const char __user *buffer, size_t count, loff_t *pos) | ||
| 1516 | { | ||
| 1517 | u32 dev_on, dev_off, dev_old, dev_new; | ||
| 1518 | ssize_t res; | ||
| 1519 | |||
| 1520 | dev_old = dev_new = viaparinfo->shared->iga2_devices; | ||
| 1521 | res = odev_update(buffer, count, &dev_new); | ||
| 1522 | if (res != count) | ||
| 1523 | return res; | ||
| 1524 | dev_off = dev_old & ~dev_new; | ||
| 1525 | dev_on = dev_new & ~dev_old; | ||
| 1526 | viaparinfo->shared->iga2_devices = dev_new; | ||
| 1527 | viaparinfo->shared->iga1_devices &= ~dev_new; | ||
| 1528 | via_set_source(dev_new, IGA2); | ||
| 1529 | return res; | ||
| 1530 | } | ||
| 1531 | |||
| 1532 | static const struct file_operations viafb_iga2_odev_proc_fops = { | ||
| 1533 | .owner = THIS_MODULE, | ||
| 1534 | .open = viafb_iga2_odev_proc_open, | ||
| 1535 | .read = seq_read, | ||
| 1536 | .llseek = seq_lseek, | ||
| 1537 | .release = single_release, | ||
| 1538 | .write = viafb_iga2_odev_proc_write, | ||
| 1539 | }; | ||
| 1540 | |||
| 1541 | #define IS_VT1636(lvds_chip) ((lvds_chip).lvds_chip_name == VT1636_LVDS) | ||
| 1542 | static void viafb_init_proc(struct viafb_shared *shared) | ||
| 1543 | { | ||
| 1544 | struct proc_dir_entry *iga1_entry, *iga2_entry, | ||
| 1545 | *viafb_entry = proc_mkdir("viafb", NULL); | ||
| 1546 | |||
| 1547 | shared->proc_entry = viafb_entry; | ||
| 1548 | if (viafb_entry) { | ||
| 1549 | #ifdef CONFIG_FB_VIA_DIRECT_PROCFS | ||
| 1550 | proc_create("dvp0", 0, viafb_entry, &viafb_dvp0_proc_fops); | ||
| 1551 | proc_create("dvp1", 0, viafb_entry, &viafb_dvp1_proc_fops); | ||
| 1552 | proc_create("dfph", 0, viafb_entry, &viafb_dfph_proc_fops); | ||
| 1553 | proc_create("dfpl", 0, viafb_entry, &viafb_dfpl_proc_fops); | ||
| 1554 | if (IS_VT1636(shared->chip_info.lvds_chip_info) | ||
| 1555 | || IS_VT1636(shared->chip_info.lvds_chip_info2)) | ||
| 1556 | proc_create("vt1636", 0, viafb_entry, | ||
| 1557 | &viafb_vt1636_proc_fops); | ||
| 1558 | #endif /* CONFIG_FB_VIA_DIRECT_PROCFS */ | ||
| 1447 | 1559 | ||
| 1560 | iga1_entry = proc_mkdir("iga1", viafb_entry); | ||
| 1561 | shared->iga1_proc_entry = iga1_entry; | ||
| 1562 | proc_create("output_devices", 0, iga1_entry, | ||
| 1563 | &viafb_iga1_odev_proc_fops); | ||
| 1564 | iga2_entry = proc_mkdir("iga2", viafb_entry); | ||
| 1565 | shared->iga2_proc_entry = iga2_entry; | ||
| 1566 | proc_create("output_devices", 0, iga2_entry, | ||
| 1567 | &viafb_iga2_odev_proc_fops); | ||
| 1448 | } | 1568 | } |
| 1449 | } | 1569 | } |
| 1450 | static void viafb_remove_proc(struct proc_dir_entry *viafb_entry) | 1570 | static void viafb_remove_proc(struct viafb_shared *shared) |
| 1451 | { | 1571 | { |
| 1452 | struct chip_information *chip_info = &viaparinfo->shared->chip_info; | 1572 | struct proc_dir_entry *viafb_entry = shared->proc_entry, |
| 1573 | *iga1_entry = shared->iga1_proc_entry, | ||
| 1574 | *iga2_entry = shared->iga2_proc_entry; | ||
| 1453 | 1575 | ||
| 1576 | if (!viafb_entry) | ||
| 1577 | return; | ||
| 1578 | |||
| 1579 | remove_proc_entry("output_devices", iga2_entry); | ||
| 1580 | remove_proc_entry("iga2", viafb_entry); | ||
| 1581 | remove_proc_entry("output_devices", iga1_entry); | ||
| 1582 | remove_proc_entry("iga1", viafb_entry); | ||
| 1583 | |||
| 1584 | #ifdef CONFIG_FB_VIA_DIRECT_PROCFS | ||
| 1454 | remove_proc_entry("dvp0", viafb_entry);/* parent dir */ | 1585 | remove_proc_entry("dvp0", viafb_entry);/* parent dir */ |
| 1455 | remove_proc_entry("dvp1", viafb_entry); | 1586 | remove_proc_entry("dvp1", viafb_entry); |
| 1456 | remove_proc_entry("dfph", viafb_entry); | 1587 | remove_proc_entry("dfph", viafb_entry); |
| 1457 | remove_proc_entry("dfpl", viafb_entry); | 1588 | remove_proc_entry("dfpl", viafb_entry); |
| 1458 | if (chip_info->lvds_chip_info.lvds_chip_name == VT1636_LVDS | 1589 | if (IS_VT1636(shared->chip_info.lvds_chip_info) |
| 1459 | || chip_info->lvds_chip_info2.lvds_chip_name == VT1636_LVDS) | 1590 | || IS_VT1636(shared->chip_info.lvds_chip_info2)) |
| 1460 | remove_proc_entry("vt1636", viafb_entry); | 1591 | remove_proc_entry("vt1636", viafb_entry); |
| 1592 | #endif /* CONFIG_FB_VIA_DIRECT_PROCFS */ | ||
| 1461 | 1593 | ||
| 1462 | remove_proc_entry("viafb", NULL); | 1594 | remove_proc_entry("viafb", NULL); |
| 1463 | } | 1595 | } |
| 1464 | 1596 | #undef IS_VT1636 | |
| 1465 | #endif /* CONFIG_FB_VIA_DIRECT_PROCFS */ | ||
| 1466 | 1597 | ||
| 1467 | static int parse_mode(const char *str, u32 *xres, u32 *yres) | 1598 | static int parse_mode(const char *str, u32 *xres, u32 *yres) |
| 1468 | { | 1599 | { |
| @@ -1671,9 +1802,7 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev) | |||
| 1671 | viafbinfo->node, viafbinfo->fix.id, default_var.xres, | 1802 | viafbinfo->node, viafbinfo->fix.id, default_var.xres, |
| 1672 | default_var.yres, default_var.bits_per_pixel); | 1803 | default_var.yres, default_var.bits_per_pixel); |
| 1673 | 1804 | ||
| 1674 | #ifdef CONFIG_FB_VIA_DIRECT_PROCFS | 1805 | viafb_init_proc(viaparinfo->shared); |
| 1675 | viafb_init_proc(&viaparinfo->shared->proc_entry); | ||
| 1676 | #endif | ||
| 1677 | viafb_init_dac(IGA2); | 1806 | viafb_init_dac(IGA2); |
| 1678 | return 0; | 1807 | return 0; |
| 1679 | 1808 | ||
| @@ -1700,9 +1829,7 @@ void __devexit via_fb_pci_remove(struct pci_dev *pdev) | |||
| 1700 | unregister_framebuffer(viafbinfo); | 1829 | unregister_framebuffer(viafbinfo); |
| 1701 | if (viafb_dual_fb) | 1830 | if (viafb_dual_fb) |
| 1702 | unregister_framebuffer(viafbinfo1); | 1831 | unregister_framebuffer(viafbinfo1); |
| 1703 | #ifdef CONFIG_FB_VIA_DIRECT_PROCFS | 1832 | viafb_remove_proc(viaparinfo->shared); |
| 1704 | viafb_remove_proc(viaparinfo->shared->proc_entry); | ||
| 1705 | #endif | ||
| 1706 | framebuffer_release(viafbinfo); | 1833 | framebuffer_release(viafbinfo); |
| 1707 | if (viafb_dual_fb) | 1834 | if (viafb_dual_fb) |
| 1708 | framebuffer_release(viafbinfo1); | 1835 | framebuffer_release(viafbinfo1); |
diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h index 945a47a63c4d..d66f963e930e 100644 --- a/drivers/video/via/viafbdev.h +++ b/drivers/video/via/viafbdev.h | |||
| @@ -44,6 +44,8 @@ struct viafb_shared { | |||
| 44 | u32 iga2_devices; | 44 | u32 iga2_devices; |
| 45 | 45 | ||
| 46 | struct proc_dir_entry *proc_entry; /*viafb proc entry */ | 46 | struct proc_dir_entry *proc_entry; /*viafb proc entry */ |
| 47 | struct proc_dir_entry *iga1_proc_entry; | ||
| 48 | struct proc_dir_entry *iga2_proc_entry; | ||
| 47 | struct viafb_dev *vdev; /* Global dev info */ | 49 | struct viafb_dev *vdev; /* Global dev info */ |
| 48 | 50 | ||
| 49 | /* All the information will be needed to set engine */ | 51 | /* All the information will be needed to set engine */ |
