Merge branch 'viafb-aux' into viafb-next
This commit is contained in:
Коммит
7b91812048
|
@ -6,4 +6,7 @@ obj-$(CONFIG_FB_VIA) += viafb.o
|
|||
|
||||
viafb-y :=viafbdev.o hw.o via_i2c.o dvi.o lcd.o ioctl.o accel.o \
|
||||
via_utility.o vt1636.o global.o tblDPASetting.o viamode.o \
|
||||
via-core.o via-gpio.o via_modesetting.o via_clock.o
|
||||
via-core.o via-gpio.o via_modesetting.o via_clock.o \
|
||||
via_aux.o via_aux_edid.o via_aux_vt1636.o via_aux_vt1632.o \
|
||||
via_aux_vt1631.o via_aux_vt1625.o via_aux_vt1622.o via_aux_vt1621.o \
|
||||
via_aux_sii164.o via_aux_ch7301.o
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
* infrastructure for devices connected via I2C
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include "via_aux.h"
|
||||
|
||||
|
||||
struct via_aux_bus *via_aux_probe(struct i2c_adapter *adap)
|
||||
{
|
||||
struct via_aux_bus *bus;
|
||||
|
||||
if (!adap)
|
||||
return NULL;
|
||||
|
||||
bus = kmalloc(sizeof(*bus), GFP_KERNEL);
|
||||
if (!bus)
|
||||
return NULL;
|
||||
|
||||
bus->adap = adap;
|
||||
INIT_LIST_HEAD(&bus->drivers);
|
||||
|
||||
via_aux_edid_probe(bus);
|
||||
via_aux_vt1636_probe(bus);
|
||||
via_aux_vt1632_probe(bus);
|
||||
via_aux_vt1631_probe(bus);
|
||||
via_aux_vt1625_probe(bus);
|
||||
via_aux_vt1622_probe(bus);
|
||||
via_aux_vt1621_probe(bus);
|
||||
via_aux_sii164_probe(bus);
|
||||
via_aux_ch7301_probe(bus);
|
||||
|
||||
return bus;
|
||||
}
|
||||
|
||||
void via_aux_free(struct via_aux_bus *bus)
|
||||
{
|
||||
struct via_aux_drv *pos, *n;
|
||||
|
||||
if (!bus)
|
||||
return;
|
||||
|
||||
list_for_each_entry_safe(pos, n, &bus->drivers, chain) {
|
||||
if (pos->cleanup)
|
||||
pos->cleanup(pos);
|
||||
|
||||
list_del(&pos->chain);
|
||||
kfree(pos->data);
|
||||
kfree(pos);
|
||||
}
|
||||
|
||||
kfree(bus);
|
||||
}
|
||||
|
||||
const struct fb_videomode *via_aux_get_preferred_mode(struct via_aux_bus *bus)
|
||||
{
|
||||
struct via_aux_drv *pos;
|
||||
const struct fb_videomode *mode = NULL;
|
||||
|
||||
if (!bus)
|
||||
return NULL;
|
||||
|
||||
list_for_each_entry(pos, &bus->drivers, chain) {
|
||||
if (pos->get_preferred_mode)
|
||||
mode = pos->get_preferred_mode(pos);
|
||||
}
|
||||
|
||||
return mode;
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
* infrastructure for devices connected via I2C
|
||||
*/
|
||||
|
||||
#ifndef __VIA_AUX_H__
|
||||
#define __VIA_AUX_H__
|
||||
|
||||
|
||||
#include <linux/list.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/fb.h>
|
||||
|
||||
|
||||
struct via_aux_bus {
|
||||
struct i2c_adapter *adap; /* the I2C device to access the bus */
|
||||
struct list_head drivers; /* drivers for devices on this bus */
|
||||
};
|
||||
|
||||
struct via_aux_drv {
|
||||
struct list_head chain; /* chain to support multiple drivers */
|
||||
|
||||
struct via_aux_bus *bus; /* the I2C bus used */
|
||||
u8 addr; /* the I2C slave address */
|
||||
|
||||
const char *name; /* human readable name of the driver */
|
||||
void *data; /* private data of this driver */
|
||||
|
||||
void (*cleanup)(struct via_aux_drv *drv);
|
||||
const struct fb_videomode* (*get_preferred_mode)
|
||||
(struct via_aux_drv *drv);
|
||||
};
|
||||
|
||||
|
||||
struct via_aux_bus *via_aux_probe(struct i2c_adapter *adap);
|
||||
void via_aux_free(struct via_aux_bus *bus);
|
||||
const struct fb_videomode *via_aux_get_preferred_mode(struct via_aux_bus *bus);
|
||||
|
||||
|
||||
static inline bool via_aux_add(struct via_aux_drv *drv)
|
||||
{
|
||||
struct via_aux_drv *data = kmalloc(sizeof(*data), GFP_KERNEL);
|
||||
|
||||
if (!data)
|
||||
return false;
|
||||
|
||||
*data = *drv;
|
||||
list_add_tail(&data->chain, &data->bus->drivers);
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool via_aux_read(struct via_aux_drv *drv, u8 start, u8 *buf,
|
||||
u8 len)
|
||||
{
|
||||
struct i2c_msg msg[2] = {
|
||||
{.addr = drv->addr, .flags = 0, .len = 1, .buf = &start},
|
||||
{.addr = drv->addr, .flags = I2C_M_RD, .len = len, .buf = buf} };
|
||||
|
||||
return i2c_transfer(drv->bus->adap, msg, 2) == 2;
|
||||
}
|
||||
|
||||
|
||||
/* probe functions of existing drivers - should only be called in via_aux.c */
|
||||
void via_aux_ch7301_probe(struct via_aux_bus *bus);
|
||||
void via_aux_edid_probe(struct via_aux_bus *bus);
|
||||
void via_aux_sii164_probe(struct via_aux_bus *bus);
|
||||
void via_aux_vt1636_probe(struct via_aux_bus *bus);
|
||||
void via_aux_vt1632_probe(struct via_aux_bus *bus);
|
||||
void via_aux_vt1631_probe(struct via_aux_bus *bus);
|
||||
void via_aux_vt1625_probe(struct via_aux_bus *bus);
|
||||
void via_aux_vt1622_probe(struct via_aux_bus *bus);
|
||||
void via_aux_vt1621_probe(struct via_aux_bus *bus);
|
||||
|
||||
|
||||
#endif /* __VIA_AUX_H__ */
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
* driver for Chrontel CH7301 DVI Transmitter
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include "via_aux.h"
|
||||
|
||||
|
||||
static const char *name = "CH7301 DVI Transmitter";
|
||||
|
||||
|
||||
static void probe(struct via_aux_bus *bus, u8 addr)
|
||||
{
|
||||
struct via_aux_drv drv = {
|
||||
.bus = bus,
|
||||
.addr = addr,
|
||||
.name = name};
|
||||
u8 tmp;
|
||||
|
||||
if (!via_aux_read(&drv, 0x4B, &tmp, 1) || tmp != 0x17)
|
||||
return;
|
||||
|
||||
printk(KERN_INFO "viafb: Found %s at address 0x%x\n", name, addr);
|
||||
via_aux_add(&drv);
|
||||
}
|
||||
|
||||
void via_aux_ch7301_probe(struct via_aux_bus *bus)
|
||||
{
|
||||
probe(bus, 0x75);
|
||||
probe(bus, 0x76);
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
* generic EDID driver
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include <linux/fb.h>
|
||||
#include "via_aux.h"
|
||||
#include "../edid.h"
|
||||
|
||||
|
||||
static const char *name = "EDID";
|
||||
|
||||
|
||||
static void query_edid(struct via_aux_drv *drv)
|
||||
{
|
||||
struct fb_monspecs *spec = drv->data;
|
||||
unsigned char edid[EDID_LENGTH];
|
||||
bool valid = false;
|
||||
|
||||
if (spec)
|
||||
fb_destroy_modedb(spec->modedb);
|
||||
else
|
||||
spec = kmalloc(sizeof(*spec), GFP_KERNEL);
|
||||
|
||||
spec->version = spec->revision = 0;
|
||||
if (via_aux_read(drv, 0x00, edid, EDID_LENGTH)) {
|
||||
fb_edid_to_monspecs(edid, spec);
|
||||
valid = spec->version || spec->revision;
|
||||
}
|
||||
|
||||
if (!valid) {
|
||||
kfree(spec);
|
||||
spec = NULL;
|
||||
} else
|
||||
printk(KERN_DEBUG "EDID: %s %s\n", spec->manufacturer, spec->monitor);
|
||||
|
||||
drv->data = spec;
|
||||
}
|
||||
|
||||
static const struct fb_videomode *get_preferred_mode(struct via_aux_drv *drv)
|
||||
{
|
||||
struct fb_monspecs *spec = drv->data;
|
||||
int i;
|
||||
|
||||
if (!spec || !spec->modedb || !(spec->misc & FB_MISC_1ST_DETAIL))
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < spec->modedb_len; i++) {
|
||||
if (spec->modedb[i].flag & FB_MODE_IS_FIRST &&
|
||||
spec->modedb[i].flag & FB_MODE_IS_DETAILED)
|
||||
return &spec->modedb[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void cleanup(struct via_aux_drv *drv)
|
||||
{
|
||||
struct fb_monspecs *spec = drv->data;
|
||||
|
||||
if (spec)
|
||||
fb_destroy_modedb(spec->modedb);
|
||||
}
|
||||
|
||||
void via_aux_edid_probe(struct via_aux_bus *bus)
|
||||
{
|
||||
struct via_aux_drv drv = {
|
||||
.bus = bus,
|
||||
.addr = 0x50,
|
||||
.name = name,
|
||||
.cleanup = cleanup,
|
||||
.get_preferred_mode = get_preferred_mode};
|
||||
|
||||
query_edid(&drv);
|
||||
|
||||
/* as EDID devices can be connected/disconnected just add the driver */
|
||||
via_aux_add(&drv);
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
* driver for Silicon Image SiI 164 PanelLink Transmitter
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include "via_aux.h"
|
||||
|
||||
|
||||
static const char *name = "SiI 164 PanelLink Transmitter";
|
||||
|
||||
|
||||
static void probe(struct via_aux_bus *bus, u8 addr)
|
||||
{
|
||||
struct via_aux_drv drv = {
|
||||
.bus = bus,
|
||||
.addr = addr,
|
||||
.name = name};
|
||||
/* check vendor id and device id */
|
||||
const u8 id[] = {0x01, 0x00, 0x06, 0x00}, len = ARRAY_SIZE(id);
|
||||
u8 tmp[len];
|
||||
|
||||
if (!via_aux_read(&drv, 0x00, tmp, len) || memcmp(id, tmp, len))
|
||||
return;
|
||||
|
||||
printk(KERN_INFO "viafb: Found %s at address 0x%x\n", name, addr);
|
||||
via_aux_add(&drv);
|
||||
}
|
||||
|
||||
void via_aux_sii164_probe(struct via_aux_bus *bus)
|
||||
{
|
||||
u8 i;
|
||||
|
||||
for (i = 0x38; i <= 0x3F; i++)
|
||||
probe(bus, i);
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
* driver for VIA VT1621(M) TV Encoder
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include "via_aux.h"
|
||||
|
||||
|
||||
static const char *name = "VT1621(M) TV Encoder";
|
||||
|
||||
|
||||
void via_aux_vt1621_probe(struct via_aux_bus *bus)
|
||||
{
|
||||
struct via_aux_drv drv = {
|
||||
.bus = bus,
|
||||
.addr = 0x20,
|
||||
.name = name};
|
||||
u8 tmp;
|
||||
|
||||
if (!via_aux_read(&drv, 0x1B, &tmp, 1) || tmp != 0x02)
|
||||
return;
|
||||
|
||||
printk(KERN_INFO "viafb: Found %s\n", name);
|
||||
via_aux_add(&drv);
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
* driver for VIA VT1622(M) Digital TV Encoder
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include "via_aux.h"
|
||||
|
||||
|
||||
static const char *name = "VT1622(M) Digital TV Encoder";
|
||||
|
||||
|
||||
static void probe(struct via_aux_bus *bus, u8 addr)
|
||||
{
|
||||
struct via_aux_drv drv = {
|
||||
.bus = bus,
|
||||
.addr = addr,
|
||||
.name = name};
|
||||
u8 tmp;
|
||||
|
||||
if (!via_aux_read(&drv, 0x1B, &tmp, 1) || tmp != 0x03)
|
||||
return;
|
||||
|
||||
printk(KERN_INFO "viafb: Found %s at address 0x%x\n", name, addr);
|
||||
via_aux_add(&drv);
|
||||
}
|
||||
|
||||
void via_aux_vt1622_probe(struct via_aux_bus *bus)
|
||||
{
|
||||
probe(bus, 0x20);
|
||||
probe(bus, 0x21);
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
* driver for VIA VT1625(M) HDTV Encoder
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include "via_aux.h"
|
||||
|
||||
|
||||
static const char *name = "VT1625(M) HDTV Encoder";
|
||||
|
||||
|
||||
static void probe(struct via_aux_bus *bus, u8 addr)
|
||||
{
|
||||
struct via_aux_drv drv = {
|
||||
.bus = bus,
|
||||
.addr = addr,
|
||||
.name = name};
|
||||
u8 tmp;
|
||||
|
||||
if (!via_aux_read(&drv, 0x1B, &tmp, 1) || tmp != 0x50)
|
||||
return;
|
||||
|
||||
printk(KERN_INFO "viafb: Found %s at address 0x%x\n", name, addr);
|
||||
via_aux_add(&drv);
|
||||
}
|
||||
|
||||
void via_aux_vt1625_probe(struct via_aux_bus *bus)
|
||||
{
|
||||
probe(bus, 0x20);
|
||||
probe(bus, 0x21);
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
* driver for VIA VT1631 LVDS Transmitter
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include "via_aux.h"
|
||||
|
||||
|
||||
static const char *name = "VT1631 LVDS Transmitter";
|
||||
|
||||
|
||||
void via_aux_vt1631_probe(struct via_aux_bus *bus)
|
||||
{
|
||||
struct via_aux_drv drv = {
|
||||
.bus = bus,
|
||||
.addr = 0x38,
|
||||
.name = name};
|
||||
/* check vendor id and device id */
|
||||
const u8 id[] = {0x06, 0x11, 0x91, 0x31}, len = ARRAY_SIZE(id);
|
||||
u8 tmp[len];
|
||||
|
||||
if (!via_aux_read(&drv, 0x00, tmp, len) || memcmp(id, tmp, len))
|
||||
return;
|
||||
|
||||
printk(KERN_INFO "viafb: Found %s\n", name);
|
||||
via_aux_add(&drv);
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
* driver for VIA VT1632 DVI Transmitter
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include "via_aux.h"
|
||||
|
||||
|
||||
static const char *name = "VT1632 DVI Transmitter";
|
||||
|
||||
|
||||
static void probe(struct via_aux_bus *bus, u8 addr)
|
||||
{
|
||||
struct via_aux_drv drv = {
|
||||
.bus = bus,
|
||||
.addr = addr,
|
||||
.name = name};
|
||||
/* check vendor id and device id */
|
||||
const u8 id[] = {0x06, 0x11, 0x92, 0x31}, len = ARRAY_SIZE(id);
|
||||
u8 tmp[len];
|
||||
|
||||
if (!via_aux_read(&drv, 0x00, tmp, len) || memcmp(id, tmp, len))
|
||||
return;
|
||||
|
||||
printk(KERN_INFO "viafb: Found %s at address 0x%x\n", name, addr);
|
||||
via_aux_add(&drv);
|
||||
}
|
||||
|
||||
void via_aux_vt1632_probe(struct via_aux_bus *bus)
|
||||
{
|
||||
u8 i;
|
||||
|
||||
for (i = 0x08; i <= 0x0F; i++)
|
||||
probe(bus, i);
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
* driver for VIA VT1636 LVDS Transmitter
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include "via_aux.h"
|
||||
|
||||
|
||||
static const char *name = "VT1636 LVDS Transmitter";
|
||||
|
||||
|
||||
void via_aux_vt1636_probe(struct via_aux_bus *bus)
|
||||
{
|
||||
struct via_aux_drv drv = {
|
||||
.bus = bus,
|
||||
.addr = 0x40,
|
||||
.name = name};
|
||||
/* check vendor id and device id */
|
||||
const u8 id[] = {0x06, 0x11, 0x45, 0x33}, len = ARRAY_SIZE(id);
|
||||
u8 tmp[len];
|
||||
|
||||
if (!via_aux_read(&drv, 0x00, tmp, len) || memcmp(id, tmp, len))
|
||||
return;
|
||||
|
||||
printk(KERN_INFO "viafb: Found %s\n", name);
|
||||
via_aux_add(&drv);
|
||||
}
|
|
@ -51,7 +51,7 @@ static void via_i2c_setscl(void *data, int state)
|
|||
val |= 0x01;
|
||||
break;
|
||||
case VIA_PORT_GPIO:
|
||||
val |= 0x80;
|
||||
val |= 0x82;
|
||||
break;
|
||||
default:
|
||||
printk(KERN_ERR "viafb_i2c: specify wrong i2c type.\n");
|
||||
|
@ -67,6 +67,9 @@ static int via_i2c_getscl(void *data)
|
|||
int ret = 0;
|
||||
|
||||
spin_lock_irqsave(&i2c_vdev->reg_lock, flags);
|
||||
if (adap_data->type == VIA_PORT_GPIO)
|
||||
via_write_reg_mask(adap_data->io_port, adap_data->ioport_index,
|
||||
0, 0x80);
|
||||
if (via_read_reg(adap_data->io_port, adap_data->ioport_index) & 0x08)
|
||||
ret = 1;
|
||||
spin_unlock_irqrestore(&i2c_vdev->reg_lock, flags);
|
||||
|
@ -80,6 +83,9 @@ static int via_i2c_getsda(void *data)
|
|||
int ret = 0;
|
||||
|
||||
spin_lock_irqsave(&i2c_vdev->reg_lock, flags);
|
||||
if (adap_data->type == VIA_PORT_GPIO)
|
||||
via_write_reg_mask(adap_data->io_port, adap_data->ioport_index,
|
||||
0, 0x40);
|
||||
if (via_read_reg(adap_data->io_port, adap_data->ioport_index) & 0x04)
|
||||
ret = 1;
|
||||
spin_unlock_irqrestore(&i2c_vdev->reg_lock, flags);
|
||||
|
@ -103,7 +109,7 @@ static void via_i2c_setsda(void *data, int state)
|
|||
val |= 0x01;
|
||||
break;
|
||||
case VIA_PORT_GPIO:
|
||||
val |= 0x40;
|
||||
val |= 0x42;
|
||||
break;
|
||||
default:
|
||||
printk(KERN_ERR "viafb_i2c: specify wrong i2c type.\n");
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/via-core.h>
|
||||
#include <linux/via_i2c.h>
|
||||
#include <asm/olpc.h>
|
||||
|
||||
#define _MASTER_FILE
|
||||
|
@ -1670,12 +1671,23 @@ static void viafb_remove_proc(struct viafb_shared *shared)
|
|||
}
|
||||
#undef IS_VT1636
|
||||
|
||||
static int parse_mode(const char *str, u32 *xres, u32 *yres)
|
||||
static int parse_mode(const char *str, u32 devices, u32 *xres, u32 *yres)
|
||||
{
|
||||
const struct fb_videomode *mode = NULL;
|
||||
char *ptr;
|
||||
|
||||
if (!str) {
|
||||
if (machine_is_olpc()) {
|
||||
if (devices == VIA_CRT)
|
||||
mode = via_aux_get_preferred_mode(
|
||||
viaparinfo->shared->i2c_26);
|
||||
else if (devices == VIA_DVP1)
|
||||
mode = via_aux_get_preferred_mode(
|
||||
viaparinfo->shared->i2c_31);
|
||||
|
||||
if (mode) {
|
||||
*xres = mode->xres;
|
||||
*yres = mode->yres;
|
||||
} else if (machine_is_olpc()) {
|
||||
*xres = 1200;
|
||||
*yres = 900;
|
||||
} else {
|
||||
|
@ -1729,6 +1741,29 @@ static struct viafb_pm_hooks viafb_fb_pm_hooks = {
|
|||
|
||||
#endif
|
||||
|
||||
static void __devinit i2c_bus_probe(struct viafb_shared *shared)
|
||||
{
|
||||
/* should be always CRT */
|
||||
printk(KERN_INFO "viafb: Probing I2C bus 0x26\n");
|
||||
shared->i2c_26 = via_aux_probe(viafb_find_i2c_adapter(VIA_PORT_26));
|
||||
|
||||
/* seems to be usually DVP1 */
|
||||
printk(KERN_INFO "viafb: Probing I2C bus 0x31\n");
|
||||
shared->i2c_31 = via_aux_probe(viafb_find_i2c_adapter(VIA_PORT_31));
|
||||
|
||||
/* FIXME: what is this? */
|
||||
printk(KERN_INFO "viafb: Probing I2C bus 0x2C\n");
|
||||
shared->i2c_2C = via_aux_probe(viafb_find_i2c_adapter(VIA_PORT_2C));
|
||||
|
||||
printk(KERN_INFO "viafb: Finished I2C bus probing");
|
||||
}
|
||||
|
||||
static void i2c_bus_free(struct viafb_shared *shared)
|
||||
{
|
||||
via_aux_free(shared->i2c_26);
|
||||
via_aux_free(shared->i2c_31);
|
||||
via_aux_free(shared->i2c_2C);
|
||||
}
|
||||
|
||||
int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
|
||||
{
|
||||
|
@ -1762,6 +1797,7 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
|
|||
&viaparinfo->shared->lvds_setting_info2;
|
||||
viaparinfo->chip_info = &viaparinfo->shared->chip_info;
|
||||
|
||||
i2c_bus_probe(viaparinfo->shared);
|
||||
if (viafb_dual_fb)
|
||||
viafb_SAMM_ON = 1;
|
||||
parse_lcd_port();
|
||||
|
@ -1804,10 +1840,11 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
|
|||
viafb_second_size * 1024 * 1024;
|
||||
}
|
||||
|
||||
parse_mode(viafb_mode, &default_xres, &default_yres);
|
||||
parse_mode(viafb_mode, viaparinfo->shared->iga1_devices,
|
||||
&default_xres, &default_yres);
|
||||
if (viafb_SAMM_ON == 1)
|
||||
parse_mode(viafb_mode1, &viafb_second_xres,
|
||||
&viafb_second_yres);
|
||||
parse_mode(viafb_mode1, viaparinfo->shared->iga2_devices,
|
||||
&viafb_second_xres, &viafb_second_yres);
|
||||
|
||||
default_var.xres = default_xres;
|
||||
default_var.yres = default_yres;
|
||||
|
@ -1915,6 +1952,7 @@ out_fb1_release:
|
|||
if (viafbinfo1)
|
||||
framebuffer_release(viafbinfo1);
|
||||
out_fb_release:
|
||||
i2c_bus_free(viaparinfo->shared);
|
||||
framebuffer_release(viafbinfo);
|
||||
return rc;
|
||||
}
|
||||
|
@ -1927,6 +1965,7 @@ void __devexit via_fb_pci_remove(struct pci_dev *pdev)
|
|||
if (viafb_dual_fb)
|
||||
unregister_framebuffer(viafbinfo1);
|
||||
viafb_remove_proc(viaparinfo->shared);
|
||||
i2c_bus_free(viaparinfo->shared);
|
||||
framebuffer_release(viafbinfo);
|
||||
if (viafb_dual_fb)
|
||||
framebuffer_release(viafbinfo1);
|
||||
|
@ -2033,9 +2072,9 @@ int __init viafb_init(void)
|
|||
if (r < 0)
|
||||
return r;
|
||||
#endif
|
||||
if (parse_mode(viafb_mode, &dummy_x, &dummy_y)
|
||||
if (parse_mode(viafb_mode, 0, &dummy_x, &dummy_y)
|
||||
|| !viafb_get_best_mode(dummy_x, dummy_y, viafb_refresh)
|
||||
|| parse_mode(viafb_mode1, &dummy_x, &dummy_y)
|
||||
|| parse_mode(viafb_mode1, 0, &dummy_x, &dummy_y)
|
||||
|| !viafb_get_best_mode(dummy_x, dummy_y, viafb_refresh1)
|
||||
|| viafb_bpp < 0 || viafb_bpp > 32
|
||||
|| viafb_bpp1 < 0 || viafb_bpp1 > 32
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <linux/fb.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include "via_aux.h"
|
||||
#include "ioctl.h"
|
||||
#include "share.h"
|
||||
#include "chip.h"
|
||||
|
@ -48,6 +49,11 @@ struct viafb_shared {
|
|||
struct proc_dir_entry *iga2_proc_entry;
|
||||
struct viafb_dev *vdev; /* Global dev info */
|
||||
|
||||
/* I2C busses that may have auxiliary devices */
|
||||
struct via_aux_bus *i2c_26;
|
||||
struct via_aux_bus *i2c_31;
|
||||
struct via_aux_bus *i2c_2C;
|
||||
|
||||
/* All the information will be needed to set engine */
|
||||
struct tmds_setting_information tmds_setting_info;
|
||||
struct lvds_setting_information lvds_setting_info;
|
||||
|
|
Загрузка…
Ссылка в новой задаче