summaryrefslogtreecommitdiffstats
path: root/drivers/video/via
diff options
context:
space:
mode:
authorFlorian Tobias Schandinat <FlorianSchandinat@gmx.de>2012-02-14 23:22:47 -0500
committerFlorian Tobias Schandinat <FlorianSchandinat@gmx.de>2012-02-14 23:22:47 -0500
commit7b918120489ea004388b7370194222671e657203 (patch)
treeedef07621f0b31cd39f491c9050ea8361d621372 /drivers/video/via
parent5b270d7bcbba26297abc38a3af566acbcc672ac6 (diff)
parent5dc5f61813a9c3ab7dd0a6982ad044834134db5a (diff)
Merge branch 'viafb-aux' into viafb-next
Diffstat (limited to 'drivers/video/via')
-rw-r--r--drivers/video/via/Makefile5
-rw-r--r--drivers/video/via/via_aux.c88
-rw-r--r--drivers/video/via/via_aux.h93
-rw-r--r--drivers/video/via/via_aux_ch7301.c50
-rw-r--r--drivers/video/via/via_aux_edid.c97
-rw-r--r--drivers/video/via/via_aux_sii164.c54
-rw-r--r--drivers/video/via/via_aux_vt1621.c44
-rw-r--r--drivers/video/via/via_aux_vt1622.c50
-rw-r--r--drivers/video/via/via_aux_vt1625.c50
-rw-r--r--drivers/video/via/via_aux_vt1631.c46
-rw-r--r--drivers/video/via/via_aux_vt1632.c54
-rw-r--r--drivers/video/via/via_aux_vt1636.c46
-rw-r--r--drivers/video/via/via_i2c.c10
-rw-r--r--drivers/video/via/viafbdev.c53
-rw-r--r--drivers/video/via/viafbdev.h6
15 files changed, 736 insertions, 10 deletions
diff --git a/drivers/video/via/Makefile b/drivers/video/via/Makefile
index 5108136e8776..159f26e6adb5 100644
--- a/drivers/video/via/Makefile
+++ b/drivers/video/via/Makefile
@@ -6,4 +6,7 @@ obj-$(CONFIG_FB_VIA) += viafb.o
6 6
7viafb-y :=viafbdev.o hw.o via_i2c.o dvi.o lcd.o ioctl.o accel.o \ 7viafb-y :=viafbdev.o hw.o via_i2c.o dvi.o lcd.o ioctl.o accel.o \
8 via_utility.o vt1636.o global.o tblDPASetting.o viamode.o \ 8 via_utility.o vt1636.o global.o tblDPASetting.o viamode.o \
9 via-core.o via-gpio.o via_modesetting.o via_clock.o 9 via-core.o via-gpio.o via_modesetting.o via_clock.o \
10 via_aux.o via_aux_edid.o via_aux_vt1636.o via_aux_vt1632.o \
11 via_aux_vt1631.o via_aux_vt1625.o via_aux_vt1622.o via_aux_vt1621.o \
12 via_aux_sii164.o via_aux_ch7301.o
diff --git a/drivers/video/via/via_aux.c b/drivers/video/via/via_aux.c
new file mode 100644
index 000000000000..4a0a55cdac3d
--- /dev/null
+++ b/drivers/video/via/via_aux.c
@@ -0,0 +1,88 @@
1/*
2 * Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License as published by the Free Software Foundation;
7 * either version 2, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
11 * the implied warranty of MERCHANTABILITY or FITNESS FOR
12 * A PARTICULAR PURPOSE.See the GNU General Public License
13 * for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc.,
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20/*
21 * infrastructure for devices connected via I2C
22 */
23
24#include <linux/slab.h>
25#include "via_aux.h"
26
27
28struct via_aux_bus *via_aux_probe(struct i2c_adapter *adap)
29{
30 struct via_aux_bus *bus;
31
32 if (!adap)
33 return NULL;
34
35 bus = kmalloc(sizeof(*bus), GFP_KERNEL);
36 if (!bus)
37 return NULL;
38
39 bus->adap = adap;
40 INIT_LIST_HEAD(&bus->drivers);
41
42 via_aux_edid_probe(bus);
43 via_aux_vt1636_probe(bus);
44 via_aux_vt1632_probe(bus);
45 via_aux_vt1631_probe(bus);
46 via_aux_vt1625_probe(bus);
47 via_aux_vt1622_probe(bus);
48 via_aux_vt1621_probe(bus);
49 via_aux_sii164_probe(bus);
50 via_aux_ch7301_probe(bus);
51
52 return bus;
53}
54
55void via_aux_free(struct via_aux_bus *bus)
56{
57 struct via_aux_drv *pos, *n;
58
59 if (!bus)
60 return;
61
62 list_for_each_entry_safe(pos, n, &bus->drivers, chain) {
63 if (pos->cleanup)
64 pos->cleanup(pos);
65
66 list_del(&pos->chain);
67 kfree(pos->data);
68 kfree(pos);
69 }
70
71 kfree(bus);
72}
73
74const struct fb_videomode *via_aux_get_preferred_mode(struct via_aux_bus *bus)
75{
76 struct via_aux_drv *pos;
77 const struct fb_videomode *mode = NULL;
78
79 if (!bus)
80 return NULL;
81
82 list_for_each_entry(pos, &bus->drivers, chain) {
83 if (pos->get_preferred_mode)
84 mode = pos->get_preferred_mode(pos);
85 }
86
87 return mode;
88}
diff --git a/drivers/video/via/via_aux.h b/drivers/video/via/via_aux.h
new file mode 100644
index 000000000000..a8de3f038cea
--- /dev/null
+++ b/drivers/video/via/via_aux.h
@@ -0,0 +1,93 @@
1/*
2 * Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License as published by the Free Software Foundation;
7 * either version 2, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
11 * the implied warranty of MERCHANTABILITY or FITNESS FOR
12 * A PARTICULAR PURPOSE.See the GNU General Public License
13 * for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc.,
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20/*
21 * infrastructure for devices connected via I2C
22 */
23
24#ifndef __VIA_AUX_H__
25#define __VIA_AUX_H__
26
27
28#include <linux/list.h>
29#include <linux/i2c.h>
30#include <linux/fb.h>
31
32
33struct via_aux_bus {
34 struct i2c_adapter *adap; /* the I2C device to access the bus */
35 struct list_head drivers; /* drivers for devices on this bus */
36};
37
38struct via_aux_drv {
39 struct list_head chain; /* chain to support multiple drivers */
40
41 struct via_aux_bus *bus; /* the I2C bus used */
42 u8 addr; /* the I2C slave address */
43
44 const char *name; /* human readable name of the driver */
45 void *data; /* private data of this driver */
46
47 void (*cleanup)(struct via_aux_drv *drv);
48 const struct fb_videomode* (*get_preferred_mode)
49 (struct via_aux_drv *drv);
50};
51
52
53struct via_aux_bus *via_aux_probe(struct i2c_adapter *adap);
54void via_aux_free(struct via_aux_bus *bus);
55const struct fb_videomode *via_aux_get_preferred_mode(struct via_aux_bus *bus);
56
57
58static inline bool via_aux_add(struct via_aux_drv *drv)
59{
60 struct via_aux_drv *data = kmalloc(sizeof(*data), GFP_KERNEL);
61
62 if (!data)
63 return false;
64
65 *data = *drv;
66 list_add_tail(&data->chain, &data->bus->drivers);
67 return true;
68}
69
70static inline bool via_aux_read(struct via_aux_drv *drv, u8 start, u8 *buf,
71 u8 len)
72{
73 struct i2c_msg msg[2] = {
74 {.addr = drv->addr, .flags = 0, .len = 1, .buf = &start},
75 {.addr = drv->addr, .flags = I2C_M_RD, .len = len, .buf = buf} };
76
77 return i2c_transfer(drv->bus->adap, msg, 2) == 2;
78}
79
80
81/* probe functions of existing drivers - should only be called in via_aux.c */
82void via_aux_ch7301_probe(struct via_aux_bus *bus);
83void via_aux_edid_probe(struct via_aux_bus *bus);
84void via_aux_sii164_probe(struct via_aux_bus *bus);
85void via_aux_vt1636_probe(struct via_aux_bus *bus);
86void via_aux_vt1632_probe(struct via_aux_bus *bus);
87void via_aux_vt1631_probe(struct via_aux_bus *bus);
88void via_aux_vt1625_probe(struct via_aux_bus *bus);
89void via_aux_vt1622_probe(struct via_aux_bus *bus);
90void via_aux_vt1621_probe(struct via_aux_bus *bus);
91
92
93#endif /* __VIA_AUX_H__ */
diff --git a/drivers/video/via/via_aux_ch7301.c b/drivers/video/via/via_aux_ch7301.c
new file mode 100644
index 000000000000..1cbe5037a6b0
--- /dev/null
+++ b/drivers/video/via/via_aux_ch7301.c
@@ -0,0 +1,50 @@
1/*
2 * Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License as published by the Free Software Foundation;
7 * either version 2, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
11 * the implied warranty of MERCHANTABILITY or FITNESS FOR
12 * A PARTICULAR PURPOSE.See the GNU General Public License
13 * for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc.,
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20/*
21 * driver for Chrontel CH7301 DVI Transmitter
22 */
23
24#include <linux/slab.h>
25#include "via_aux.h"
26
27
28static const char *name = "CH7301 DVI Transmitter";
29
30
31static void probe(struct via_aux_bus *bus, u8 addr)
32{
33 struct via_aux_drv drv = {
34 .bus = bus,
35 .addr = addr,
36 .name = name};
37 u8 tmp;
38
39 if (!via_aux_read(&drv, 0x4B, &tmp, 1) || tmp != 0x17)
40 return;
41
42 printk(KERN_INFO "viafb: Found %s at address 0x%x\n", name, addr);
43 via_aux_add(&drv);
44}
45
46void via_aux_ch7301_probe(struct via_aux_bus *bus)
47{
48 probe(bus, 0x75);
49 probe(bus, 0x76);
50}
diff --git a/drivers/video/via/via_aux_edid.c b/drivers/video/via/via_aux_edid.c
new file mode 100644
index 000000000000..03f7a41c8a3f
--- /dev/null
+++ b/drivers/video/via/via_aux_edid.c
@@ -0,0 +1,97 @@
1/*
2 * Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License as published by the Free Software Foundation;
7 * either version 2, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
11 * the implied warranty of MERCHANTABILITY or FITNESS FOR
12 * A PARTICULAR PURPOSE.See the GNU General Public License
13 * for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc.,
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20/*
21 * generic EDID driver
22 */
23
24#include <linux/slab.h>
25#include <linux/fb.h>
26#include "via_aux.h"
27#include "../edid.h"
28
29
30static const char *name = "EDID";
31
32
33static void query_edid(struct via_aux_drv *drv)
34{
35 struct fb_monspecs *spec = drv->data;
36 unsigned char edid[EDID_LENGTH];
37 bool valid = false;
38
39 if (spec)
40 fb_destroy_modedb(spec->modedb);
41 else
42 spec = kmalloc(sizeof(*spec), GFP_KERNEL);
43
44 spec->version = spec->revision = 0;
45 if (via_aux_read(drv, 0x00, edid, EDID_LENGTH)) {
46 fb_edid_to_monspecs(edid, spec);
47 valid = spec->version || spec->revision;
48 }
49
50 if (!valid) {
51 kfree(spec);
52 spec = NULL;
53 } else
54 printk(KERN_DEBUG "EDID: %s %s\n", spec->manufacturer, spec->monitor);
55
56 drv->data = spec;
57}
58
59static const struct fb_videomode *get_preferred_mode(struct via_aux_drv *drv)
60{
61 struct fb_monspecs *spec = drv->data;
62 int i;
63
64 if (!spec || !spec->modedb || !(spec->misc & FB_MISC_1ST_DETAIL))
65 return NULL;
66
67 for (i = 0; i < spec->modedb_len; i++) {
68 if (spec->modedb[i].flag & FB_MODE_IS_FIRST &&
69 spec->modedb[i].flag & FB_MODE_IS_DETAILED)
70 return &spec->modedb[i];
71 }
72
73 return NULL;
74}
75
76static void cleanup(struct via_aux_drv *drv)
77{
78 struct fb_monspecs *spec = drv->data;
79
80 if (spec)
81 fb_destroy_modedb(spec->modedb);
82}
83
84void via_aux_edid_probe(struct via_aux_bus *bus)
85{
86 struct via_aux_drv drv = {
87 .bus = bus,
88 .addr = 0x50,
89 .name = name,
90 .cleanup = cleanup,
91 .get_preferred_mode = get_preferred_mode};
92
93 query_edid(&drv);
94
95 /* as EDID devices can be connected/disconnected just add the driver */
96 via_aux_add(&drv);
97}
diff --git a/drivers/video/via/via_aux_sii164.c b/drivers/video/via/via_aux_sii164.c
new file mode 100644
index 000000000000..ca1b35f033b1
--- /dev/null
+++ b/drivers/video/via/via_aux_sii164.c
@@ -0,0 +1,54 @@
1/*
2 * Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License as published by the Free Software Foundation;
7 * either version 2, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
11 * the implied warranty of MERCHANTABILITY or FITNESS FOR
12 * A PARTICULAR PURPOSE.See the GNU General Public License
13 * for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc.,
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20/*
21 * driver for Silicon Image SiI 164 PanelLink Transmitter
22 */
23
24#include <linux/slab.h>
25#include "via_aux.h"
26
27
28static const char *name = "SiI 164 PanelLink Transmitter";
29
30
31static void probe(struct via_aux_bus *bus, u8 addr)
32{
33 struct via_aux_drv drv = {
34 .bus = bus,
35 .addr = addr,
36 .name = name};
37 /* check vendor id and device id */
38 const u8 id[] = {0x01, 0x00, 0x06, 0x00}, len = ARRAY_SIZE(id);
39 u8 tmp[len];
40
41 if (!via_aux_read(&drv, 0x00, tmp, len) || memcmp(id, tmp, len))
42 return;
43
44 printk(KERN_INFO "viafb: Found %s at address 0x%x\n", name, addr);
45 via_aux_add(&drv);
46}
47
48void via_aux_sii164_probe(struct via_aux_bus *bus)
49{
50 u8 i;
51
52 for (i = 0x38; i <= 0x3F; i++)
53 probe(bus, i);
54}
diff --git a/drivers/video/via/via_aux_vt1621.c b/drivers/video/via/via_aux_vt1621.c
new file mode 100644
index 000000000000..38eca8479898
--- /dev/null
+++ b/drivers/video/via/via_aux_vt1621.c
@@ -0,0 +1,44 @@
1/*
2 * Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License as published by the Free Software Foundation;
7 * either version 2, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
11 * the implied warranty of MERCHANTABILITY or FITNESS FOR
12 * A PARTICULAR PURPOSE.See the GNU General Public License
13 * for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc.,
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20/*
21 * driver for VIA VT1621(M) TV Encoder
22 */
23
24#include <linux/slab.h>
25#include "via_aux.h"
26
27
28static const char *name = "VT1621(M) TV Encoder";
29
30
31void via_aux_vt1621_probe(struct via_aux_bus *bus)
32{
33 struct via_aux_drv drv = {
34 .bus = bus,
35 .addr = 0x20,
36 .name = name};
37 u8 tmp;
38
39 if (!via_aux_read(&drv, 0x1B, &tmp, 1) || tmp != 0x02)
40 return;
41
42 printk(KERN_INFO "viafb: Found %s\n", name);
43 via_aux_add(&drv);
44}
diff --git a/drivers/video/via/via_aux_vt1622.c b/drivers/video/via/via_aux_vt1622.c
new file mode 100644
index 000000000000..8c79c68ba683
--- /dev/null
+++ b/drivers/video/via/via_aux_vt1622.c
@@ -0,0 +1,50 @@
1/*
2 * Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License as published by the Free Software Foundation;
7 * either version 2, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
11 * the implied warranty of MERCHANTABILITY or FITNESS FOR
12 * A PARTICULAR PURPOSE.See the GNU General Public License
13 * for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc.,
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20/*
21 * driver for VIA VT1622(M) Digital TV Encoder
22 */
23
24#include <linux/slab.h>
25#include "via_aux.h"
26
27
28static const char *name = "VT1622(M) Digital TV Encoder";
29
30
31static void probe(struct via_aux_bus *bus, u8 addr)
32{
33 struct via_aux_drv drv = {
34 .bus = bus,
35 .addr = addr,
36 .name = name};
37 u8 tmp;
38
39 if (!via_aux_read(&drv, 0x1B, &tmp, 1) || tmp != 0x03)
40 return;
41
42 printk(KERN_INFO "viafb: Found %s at address 0x%x\n", name, addr);
43 via_aux_add(&drv);
44}
45
46void via_aux_vt1622_probe(struct via_aux_bus *bus)
47{
48 probe(bus, 0x20);
49 probe(bus, 0x21);
50}
diff --git a/drivers/video/via/via_aux_vt1625.c b/drivers/video/via/via_aux_vt1625.c
new file mode 100644
index 000000000000..03eb30165d36
--- /dev/null
+++ b/drivers/video/via/via_aux_vt1625.c
@@ -0,0 +1,50 @@
1/*
2 * Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License as published by the Free Software Foundation;
7 * either version 2, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
11 * the implied warranty of MERCHANTABILITY or FITNESS FOR
12 * A PARTICULAR PURPOSE.See the GNU General Public License
13 * for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc.,
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20/*
21 * driver for VIA VT1625(M) HDTV Encoder
22 */
23
24#include <linux/slab.h>
25#include "via_aux.h"
26
27
28static const char *name = "VT1625(M) HDTV Encoder";
29
30
31static void probe(struct via_aux_bus *bus, u8 addr)
32{
33 struct via_aux_drv drv = {
34 .bus = bus,
35 .addr = addr,
36 .name = name};
37 u8 tmp;
38
39 if (!via_aux_read(&drv, 0x1B, &tmp, 1) || tmp != 0x50)
40 return;
41
42 printk(KERN_INFO "viafb: Found %s at address 0x%x\n", name, addr);
43 via_aux_add(&drv);
44}
45
46void via_aux_vt1625_probe(struct via_aux_bus *bus)
47{
48 probe(bus, 0x20);
49 probe(bus, 0x21);
50}
diff --git a/drivers/video/via/via_aux_vt1631.c b/drivers/video/via/via_aux_vt1631.c
new file mode 100644
index 000000000000..06e742f1f723
--- /dev/null
+++ b/drivers/video/via/via_aux_vt1631.c
@@ -0,0 +1,46 @@
1/*
2 * Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License as published by the Free Software Foundation;
7 * either version 2, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
11 * the implied warranty of MERCHANTABILITY or FITNESS FOR
12 * A PARTICULAR PURPOSE.See the GNU General Public License
13 * for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc.,
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20/*
21 * driver for VIA VT1631 LVDS Transmitter
22 */
23
24#include <linux/slab.h>
25#include "via_aux.h"
26
27
28static const char *name = "VT1631 LVDS Transmitter";
29
30
31void via_aux_vt1631_probe(struct via_aux_bus *bus)
32{
33 struct via_aux_drv drv = {
34 .bus = bus,
35 .addr = 0x38,
36 .name = name};
37 /* check vendor id and device id */
38 const u8 id[] = {0x06, 0x11, 0x91, 0x31}, len = ARRAY_SIZE(id);
39 u8 tmp[len];
40
41 if (!via_aux_read(&drv, 0x00, tmp, len) || memcmp(id, tmp, len))
42 return;
43
44 printk(KERN_INFO "viafb: Found %s\n", name);
45 via_aux_add(&drv);
46}
diff --git a/drivers/video/via/via_aux_vt1632.c b/drivers/video/via/via_aux_vt1632.c
new file mode 100644
index 000000000000..d24f4cd97401
--- /dev/null
+++ b/drivers/video/via/via_aux_vt1632.c
@@ -0,0 +1,54 @@
1/*
2 * Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License as published by the Free Software Foundation;
7 * either version 2, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
11 * the implied warranty of MERCHANTABILITY or FITNESS FOR
12 * A PARTICULAR PURPOSE.See the GNU General Public License
13 * for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc.,
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20/*
21 * driver for VIA VT1632 DVI Transmitter
22 */
23
24#include <linux/slab.h>
25#include "via_aux.h"
26
27
28static const char *name = "VT1632 DVI Transmitter";
29
30
31static void probe(struct via_aux_bus *bus, u8 addr)
32{
33 struct via_aux_drv drv = {
34 .bus = bus,
35 .addr = addr,
36 .name = name};
37 /* check vendor id and device id */
38 const u8 id[] = {0x06, 0x11, 0x92, 0x31}, len = ARRAY_SIZE(id);
39 u8 tmp[len];
40
41 if (!via_aux_read(&drv, 0x00, tmp, len) || memcmp(id, tmp, len))
42 return;
43
44 printk(KERN_INFO "viafb: Found %s at address 0x%x\n", name, addr);
45 via_aux_add(&drv);
46}
47
48void via_aux_vt1632_probe(struct via_aux_bus *bus)
49{
50 u8 i;
51
52 for (i = 0x08; i <= 0x0F; i++)
53 probe(bus, i);
54}
diff --git a/drivers/video/via/via_aux_vt1636.c b/drivers/video/via/via_aux_vt1636.c
new file mode 100644
index 000000000000..9e015c101d4d
--- /dev/null
+++ b/drivers/video/via/via_aux_vt1636.c
@@ -0,0 +1,46 @@
1/*
2 * Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License as published by the Free Software Foundation;
7 * either version 2, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
11 * the implied warranty of MERCHANTABILITY or FITNESS FOR
12 * A PARTICULAR PURPOSE.See the GNU General Public License
13 * for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc.,
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20/*
21 * driver for VIA VT1636 LVDS Transmitter
22 */
23
24#include <linux/slab.h>
25#include "via_aux.h"
26
27
28static const char *name = "VT1636 LVDS Transmitter";
29
30
31void via_aux_vt1636_probe(struct via_aux_bus *bus)
32{
33 struct via_aux_drv drv = {
34 .bus = bus,
35 .addr = 0x40,
36 .name = name};
37 /* check vendor id and device id */
38 const u8 id[] = {0x06, 0x11, 0x45, 0x33}, len = ARRAY_SIZE(id);
39 u8 tmp[len];
40
41 if (!via_aux_read(&drv, 0x00, tmp, len) || memcmp(id, tmp, len))
42 return;
43
44 printk(KERN_INFO "viafb: Found %s\n", name);
45 via_aux_add(&drv);
46}
diff --git a/drivers/video/via/via_i2c.c b/drivers/video/via/via_i2c.c
index 78f1405dbab7..dd53058bbbb7 100644
--- a/drivers/video/via/via_i2c.c
+++ b/drivers/video/via/via_i2c.c
@@ -51,7 +51,7 @@ static void via_i2c_setscl(void *data, int state)
51 val |= 0x01; 51 val |= 0x01;
52 break; 52 break;
53 case VIA_PORT_GPIO: 53 case VIA_PORT_GPIO:
54 val |= 0x80; 54 val |= 0x82;
55 break; 55 break;
56 default: 56 default:
57 printk(KERN_ERR "viafb_i2c: specify wrong i2c type.\n"); 57 printk(KERN_ERR "viafb_i2c: specify wrong i2c type.\n");
@@ -67,6 +67,9 @@ static int via_i2c_getscl(void *data)
67 int ret = 0; 67 int ret = 0;
68 68
69 spin_lock_irqsave(&i2c_vdev->reg_lock, flags); 69 spin_lock_irqsave(&i2c_vdev->reg_lock, flags);
70 if (adap_data->type == VIA_PORT_GPIO)
71 via_write_reg_mask(adap_data->io_port, adap_data->ioport_index,
72 0, 0x80);
70 if (via_read_reg(adap_data->io_port, adap_data->ioport_index) & 0x08) 73 if (via_read_reg(adap_data->io_port, adap_data->ioport_index) & 0x08)
71 ret = 1; 74 ret = 1;
72 spin_unlock_irqrestore(&i2c_vdev->reg_lock, flags); 75 spin_unlock_irqrestore(&i2c_vdev->reg_lock, flags);
@@ -80,6 +83,9 @@ static int via_i2c_getsda(void *data)
80 int ret = 0; 83 int ret = 0;
81 84
82 spin_lock_irqsave(&i2c_vdev->reg_lock, flags); 85 spin_lock_irqsave(&i2c_vdev->reg_lock, flags);
86 if (adap_data->type == VIA_PORT_GPIO)
87 via_write_reg_mask(adap_data->io_port, adap_data->ioport_index,
88 0, 0x40);
83 if (via_read_reg(adap_data->io_port, adap_data->ioport_index) & 0x04) 89 if (via_read_reg(adap_data->io_port, adap_data->ioport_index) & 0x04)
84 ret = 1; 90 ret = 1;
85 spin_unlock_irqrestore(&i2c_vdev->reg_lock, flags); 91 spin_unlock_irqrestore(&i2c_vdev->reg_lock, flags);
@@ -103,7 +109,7 @@ static void via_i2c_setsda(void *data, int state)
103 val |= 0x01; 109 val |= 0x01;
104 break; 110 break;
105 case VIA_PORT_GPIO: 111 case VIA_PORT_GPIO:
106 val |= 0x40; 112 val |= 0x42;
107 break; 113 break;
108 default: 114 default:
109 printk(KERN_ERR "viafb_i2c: specify wrong i2c type.\n"); 115 printk(KERN_ERR "viafb_i2c: specify wrong i2c type.\n");
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c
index a13c258bd32f..47911658f684 100644
--- a/drivers/video/via/viafbdev.c
+++ b/drivers/video/via/viafbdev.c
@@ -24,6 +24,7 @@
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/stat.h> 25#include <linux/stat.h>
26#include <linux/via-core.h> 26#include <linux/via-core.h>
27#include <linux/via_i2c.h>
27#include <asm/olpc.h> 28#include <asm/olpc.h>
28 29
29#define _MASTER_FILE 30#define _MASTER_FILE
@@ -1670,12 +1671,23 @@ static void viafb_remove_proc(struct viafb_shared *shared)
1670} 1671}
1671#undef IS_VT1636 1672#undef IS_VT1636
1672 1673
1673static int parse_mode(const char *str, u32 *xres, u32 *yres) 1674static int parse_mode(const char *str, u32 devices, u32 *xres, u32 *yres)
1674{ 1675{
1676 const struct fb_videomode *mode = NULL;
1675 char *ptr; 1677 char *ptr;
1676 1678
1677 if (!str) { 1679 if (!str) {
1678 if (machine_is_olpc()) { 1680 if (devices == VIA_CRT)
1681 mode = via_aux_get_preferred_mode(
1682 viaparinfo->shared->i2c_26);
1683 else if (devices == VIA_DVP1)
1684 mode = via_aux_get_preferred_mode(
1685 viaparinfo->shared->i2c_31);
1686
1687 if (mode) {
1688 *xres = mode->xres;
1689 *yres = mode->yres;
1690 } else if (machine_is_olpc()) {
1679 *xres = 1200; 1691 *xres = 1200;
1680 *yres = 900; 1692 *yres = 900;
1681 } else { 1693 } else {
@@ -1729,6 +1741,29 @@ static struct viafb_pm_hooks viafb_fb_pm_hooks = {
1729 1741
1730#endif 1742#endif
1731 1743
1744static void __devinit i2c_bus_probe(struct viafb_shared *shared)
1745{
1746 /* should be always CRT */
1747 printk(KERN_INFO "viafb: Probing I2C bus 0x26\n");
1748 shared->i2c_26 = via_aux_probe(viafb_find_i2c_adapter(VIA_PORT_26));
1749
1750 /* seems to be usually DVP1 */
1751 printk(KERN_INFO "viafb: Probing I2C bus 0x31\n");
1752 shared->i2c_31 = via_aux_probe(viafb_find_i2c_adapter(VIA_PORT_31));
1753
1754 /* FIXME: what is this? */
1755 printk(KERN_INFO "viafb: Probing I2C bus 0x2C\n");
1756 shared->i2c_2C = via_aux_probe(viafb_find_i2c_adapter(VIA_PORT_2C));
1757
1758 printk(KERN_INFO "viafb: Finished I2C bus probing");
1759}
1760
1761static void i2c_bus_free(struct viafb_shared *shared)
1762{
1763 via_aux_free(shared->i2c_26);
1764 via_aux_free(shared->i2c_31);
1765 via_aux_free(shared->i2c_2C);
1766}
1732 1767
1733int __devinit via_fb_pci_probe(struct viafb_dev *vdev) 1768int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
1734{ 1769{
@@ -1762,6 +1797,7 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
1762 &viaparinfo->shared->lvds_setting_info2; 1797 &viaparinfo->shared->lvds_setting_info2;
1763 viaparinfo->chip_info = &viaparinfo->shared->chip_info; 1798 viaparinfo->chip_info = &viaparinfo->shared->chip_info;
1764 1799
1800 i2c_bus_probe(viaparinfo->shared);
1765 if (viafb_dual_fb) 1801 if (viafb_dual_fb)
1766 viafb_SAMM_ON = 1; 1802 viafb_SAMM_ON = 1;
1767 parse_lcd_port(); 1803 parse_lcd_port();
@@ -1804,10 +1840,11 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
1804 viafb_second_size * 1024 * 1024; 1840 viafb_second_size * 1024 * 1024;
1805 } 1841 }
1806 1842
1807 parse_mode(viafb_mode, &default_xres, &default_yres); 1843 parse_mode(viafb_mode, viaparinfo->shared->iga1_devices,
1844 &default_xres, &default_yres);
1808 if (viafb_SAMM_ON == 1) 1845 if (viafb_SAMM_ON == 1)
1809 parse_mode(viafb_mode1, &viafb_second_xres, 1846 parse_mode(viafb_mode1, viaparinfo->shared->iga2_devices,
1810 &viafb_second_yres); 1847 &viafb_second_xres, &viafb_second_yres);
1811 1848
1812 default_var.xres = default_xres; 1849 default_var.xres = default_xres;
1813 default_var.yres = default_yres; 1850 default_var.yres = default_yres;
@@ -1915,6 +1952,7 @@ out_fb1_release:
1915 if (viafbinfo1) 1952 if (viafbinfo1)
1916 framebuffer_release(viafbinfo1); 1953 framebuffer_release(viafbinfo1);
1917out_fb_release: 1954out_fb_release:
1955 i2c_bus_free(viaparinfo->shared);
1918 framebuffer_release(viafbinfo); 1956 framebuffer_release(viafbinfo);
1919 return rc; 1957 return rc;
1920} 1958}
@@ -1927,6 +1965,7 @@ void __devexit via_fb_pci_remove(struct pci_dev *pdev)
1927 if (viafb_dual_fb) 1965 if (viafb_dual_fb)
1928 unregister_framebuffer(viafbinfo1); 1966 unregister_framebuffer(viafbinfo1);
1929 viafb_remove_proc(viaparinfo->shared); 1967 viafb_remove_proc(viaparinfo->shared);
1968 i2c_bus_free(viaparinfo->shared);
1930 framebuffer_release(viafbinfo); 1969 framebuffer_release(viafbinfo);
1931 if (viafb_dual_fb) 1970 if (viafb_dual_fb)
1932 framebuffer_release(viafbinfo1); 1971 framebuffer_release(viafbinfo1);
@@ -2033,9 +2072,9 @@ int __init viafb_init(void)
2033 if (r < 0) 2072 if (r < 0)
2034 return r; 2073 return r;
2035#endif 2074#endif
2036 if (parse_mode(viafb_mode, &dummy_x, &dummy_y) 2075 if (parse_mode(viafb_mode, 0, &dummy_x, &dummy_y)
2037 || !viafb_get_best_mode(dummy_x, dummy_y, viafb_refresh) 2076 || !viafb_get_best_mode(dummy_x, dummy_y, viafb_refresh)
2038 || parse_mode(viafb_mode1, &dummy_x, &dummy_y) 2077 || parse_mode(viafb_mode1, 0, &dummy_x, &dummy_y)
2039 || !viafb_get_best_mode(dummy_x, dummy_y, viafb_refresh1) 2078 || !viafb_get_best_mode(dummy_x, dummy_y, viafb_refresh1)
2040 || viafb_bpp < 0 || viafb_bpp > 32 2079 || viafb_bpp < 0 || viafb_bpp > 32
2041 || viafb_bpp1 < 0 || viafb_bpp1 > 32 2080 || viafb_bpp1 < 0 || viafb_bpp1 > 32
diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h
index d9440635d1d4..f6b2ddf56e94 100644
--- a/drivers/video/via/viafbdev.h
+++ b/drivers/video/via/viafbdev.h
@@ -26,6 +26,7 @@
26#include <linux/fb.h> 26#include <linux/fb.h>
27#include <linux/spinlock.h> 27#include <linux/spinlock.h>
28 28
29#include "via_aux.h"
29#include "ioctl.h" 30#include "ioctl.h"
30#include "share.h" 31#include "share.h"
31#include "chip.h" 32#include "chip.h"
@@ -48,6 +49,11 @@ struct viafb_shared {
48 struct proc_dir_entry *iga2_proc_entry; 49 struct proc_dir_entry *iga2_proc_entry;
49 struct viafb_dev *vdev; /* Global dev info */ 50 struct viafb_dev *vdev; /* Global dev info */
50 51
52 /* I2C busses that may have auxiliary devices */
53 struct via_aux_bus *i2c_26;
54 struct via_aux_bus *i2c_31;
55 struct via_aux_bus *i2c_2C;
56
51 /* All the information will be needed to set engine */ 57 /* All the information will be needed to set engine */
52 struct tmds_setting_information tmds_setting_info; 58 struct tmds_setting_information tmds_setting_info;
53 struct lvds_setting_information lvds_setting_info; 59 struct lvds_setting_information lvds_setting_info;