提交 a094c0af 编写于 作者: L Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6: (27 commits)
  Staging: sep: return -EFAULT on copy_to_user errors
  Staging: rc2860: return -EFAULT on copy_to_user errors
  Staging: Eliminate a NULL pointer dereference
  staging: Use GFP_ATOMIC when a lock is held
  Staging: comedi - correct parameter gainlkup for DAQCard-6024E in driver ni_mio_cs.c
  Staging: comedi: fixing ni_labpc to mite dependancy
  Staging: wlags49_h2, wlags49_h25: fixed Kconfig dependencies
  Staging: phison: depends on ATA_BMDMA
  Staging: iio-utils: fix memory overflow for dynamically allocateded memory to hold filename
  Staging: adis16255: add proper section markings to hotplug funcs
  Staging: adis16255: fix typo in Kconfig
  Staging: batman-adv: Don't allocate icmp packet with GFP_KERNEL
  Staging: batman-adv: Don't call free_netdev twice
  Staging: batman-adv: Call unregister_netdev on failures to get rtnl lock
  Staging: batman-adv: fix rogue packets on shutdown
  Staging: add MSM framebuffer driver
  Staging: comedi: fixing ni_tio to mite PCI dependancy
  Staging: comedi: fix 8255 and DAS08 Kconfig dependancies.
  Staging: comedi: For COMEDI_BUFINFO, check access to command
  Staging: comedi: COMEDI_BUFINFO with no async - report no bytes read or written
  ...
......@@ -141,5 +141,11 @@ source "drivers/staging/ti-st/Kconfig"
source "drivers/staging/adis16255/Kconfig"
source "drivers/staging/xgifb/Kconfig"
source "drivers/staging/mrst-touchscreen/Kconfig"
source "drivers/staging/msm/Kconfig"
endif # !STAGING_EXCLUDE_BUILD
endif # STAGING
......@@ -51,3 +51,6 @@ obj-$(CONFIG_CRYSTALHD) += crystalhd/
obj-$(CONFIG_CXT1E1) += cxt1e1/
obj-$(CONFIG_TI_ST) += ti-st/
obj-$(CONFIG_ADIS16255) += adis16255/
obj-$(CONFIG_FB_XGI) += xgifb/
obj-$(CONFIG_TOUCHSCREEN_MRSTOUCH) += mrst-touchscreen/
obj-$(CONFIG_MSM_STAGING) += msm/
config ADIS16255
tristate "Ananlog Devices ADIS16250/16255"
tristate "Analog Devices ADIS16250/16255"
depends on SPI && SYSFS
---help---
If you say yes here you get support for the Analog Devices
......
......@@ -361,7 +361,7 @@ static int spi_adis16255_bringup(struct spi_adis16255_data *spiadis)
/*-------------------------------------------------------------------------*/
static int spi_adis16255_probe(struct spi_device *spi)
static int __devinit spi_adis16255_probe(struct spi_device *spi)
{
struct adis16255_init_data *init_data = spi->dev.platform_data;
......@@ -421,7 +421,7 @@ static int spi_adis16255_probe(struct spi_device *spi)
return status;
}
static int spi_adis16255_remove(struct spi_device *spi)
static int __devexit spi_adis16255_remove(struct spi_device *spi)
{
struct spi_adis16255_data *spiadis = dev_get_drvdata(&spi->dev);
......
......@@ -309,7 +309,7 @@ void bat_device_add_packet(struct device_client *device_client,
struct device_packet *device_packet;
unsigned long flags;
device_packet = kmalloc(sizeof(struct device_packet), GFP_KERNEL);
device_packet = kmalloc(sizeof(struct device_packet), GFP_ATOMIC);
if (!device_packet)
return;
......
......@@ -127,7 +127,10 @@ int init_module(void)
return 0;
unreg_soft_device:
unregister_netdevice(soft_device);
unregister_netdev(soft_device);
soft_device = NULL;
return -ENOMEM;
free_soft_device:
free_netdev(soft_device);
soft_device = NULL;
......
......@@ -440,6 +440,9 @@ void send_outstanding_bcast_packet(struct work_struct *work)
hlist_del(&forw_packet->list);
spin_unlock_irqrestore(&forw_bcast_list_lock, flags);
if (atomic_read(&module_state) == MODULE_DEACTIVATING)
goto out;
/* rebroadcast packet */
rcu_read_lock();
list_for_each_entry_rcu(batman_if, &if_list, list) {
......@@ -453,15 +456,15 @@ void send_outstanding_bcast_packet(struct work_struct *work)
forw_packet->num_packets++;
/* if we still have some more bcasts to send and we are not shutting
* down */
if ((forw_packet->num_packets < 3) &&
(atomic_read(&module_state) != MODULE_DEACTIVATING))
/* if we still have some more bcasts to send */
if (forw_packet->num_packets < 3) {
_add_bcast_packet_to_list(forw_packet, ((5 * HZ) / 1000));
else {
forw_packet_free(forw_packet);
atomic_inc(&bcast_queue_left);
return;
}
out:
forw_packet_free(forw_packet);
atomic_inc(&bcast_queue_left);
}
void send_outstanding_bat_packet(struct work_struct *work)
......@@ -476,6 +479,9 @@ void send_outstanding_bat_packet(struct work_struct *work)
hlist_del(&forw_packet->list);
spin_unlock_irqrestore(&forw_bat_list_lock, flags);
if (atomic_read(&module_state) == MODULE_DEACTIVATING)
goto out;
send_packet(forw_packet);
/**
......@@ -483,10 +489,10 @@ void send_outstanding_bat_packet(struct work_struct *work)
* to determine the queues wake up time unless we are
* shutting down
*/
if ((forw_packet->own) &&
(atomic_read(&module_state) != MODULE_DEACTIVATING))
if (forw_packet->own)
schedule_own_packet(forw_packet->if_incoming);
out:
/* don't count own packet */
if (!forw_packet->own)
atomic_inc(&batman_queue_left);
......
......@@ -100,15 +100,6 @@ menuconfig COMEDI_ISA_DRIVERS
if COMEDI_ISA_DRIVERS && ISA
config COMEDI_8255
tristate "Generic 8255 support"
default N
---help---
Enable generic 8255 support.
To compile this driver as a module, choose M here: the module will be
called 8255.
config COMEDI_ACL7225B
tristate "ADlink NuDAQ ACL-7225b and compatibles support"
default N
......@@ -130,6 +121,7 @@ config COMEDI_PCL711
config COMEDI_PCL724
tristate "Advantech PCL-722/724/731 and ADlink ACL-7122/7124/PET-48DIO"
select COMEDI_8255
default N
---help---
Enable support for Advantech PCL-724, PCL-722, PCL-731 and
......@@ -198,6 +190,7 @@ config COMEDI_PCL818
config COMEDI_PCM3724
tristate "Advantech PCM-3724 PC/104 card support"
select COMEDI_8255
default N
---help---
Enable support for Advantech PCM-3724 PC/104 cards.
......@@ -232,18 +225,9 @@ config COMEDI_RTI802
To compile this driver as a module, choose M here: the module will be
called rti802.
config COMEDI_DAS08
tristate "DAS-08 compatible ISA, PC/104 and PCMCIA card support"
default N
---help---
Enable support for Keithley Metrabyte/ComputerBoards DAS08
and compatible ISA and PC/104 cards
To compile this driver as a module, choose M here: the module will be
called das08.
config COMEDI_DAS16M1
tristate "MeasurementComputing CIO-DAS16/M1DAS-16 ISA card support"
select COMEDI_8255
select COMEDI_FC
default N
---help---
......@@ -254,6 +238,7 @@ config COMEDI_DAS16M1
config COMEDI_DAS16
tristate "DAS-16 compatible ISA and PC/104 card support"
select COMEDI_8255
select COMEDI_FC
default N
---help---
......@@ -385,6 +370,7 @@ config COMEDI_FL512
config COMEDI_AIO_AIO12_8
tristate "I/O Products PC/104 AIO12-8 Analog I/O Board support"
select COMEDI_8255
default N
---help---
Enable support for I/O Products PC/104 AIO12-8 Analog I/O Board
......@@ -466,6 +452,7 @@ config COMEDI_NI_ATMIO
config COMEDI_NI_ATMIO16D
tristate "NI AT-MIO16/AT-MIO16D series ISA-PNP card support"
depends on ISAPNP && COMEDI_NI_COMMON
select COMEDI_8255
default N
---help---
Enable support for National Instruments AT-MIO16/AT-MIO16D cards.
......@@ -667,6 +654,7 @@ config COMEDI_ADDI_APCI_3XXX
config COMEDI_ADL_PCI6208
tristate "ADLink PCI-6208A support"
select COMEDI_8255
default N
---help---
Enable support for ADLink PCI-6208A cards
......@@ -751,6 +739,7 @@ config COMEDI_ADV_PCI1723
config COMEDI_ADV_PCI_DIO
tristate "Advantech PCI DIO card support"
select COMEDI_8255
default N
---help---
Enable support for Advantech PCI DIO cards
......@@ -762,6 +751,7 @@ config COMEDI_ADV_PCI_DIO
config COMEDI_AMPLC_DIO200
tristate "Amplicon PC272E and PCI272 DIO board support"
select COMEDI_8255
default N
---help---
Enable support for Amplicon PC272E and PCI272 DIO boards
......@@ -771,6 +761,7 @@ config COMEDI_AMPLC_DIO200
config COMEDI_AMPLC_PC236
tristate "Amplicon PC36AT and PCI236 DIO board support"
select COMEDI_8255
default N
---help---
Enable support for Amplicon PC36AT and PCI236 DIO boards
......@@ -799,6 +790,7 @@ config COMEDI_AMPLC_PCI224
config COMEDI_AMPLC_PCI230
tristate "Amplicon PCI230 and PCI260 support"
select COMEDI_8255
default N
---help---
Enable support for Amplicon PCI230 and PCI260 Multifunction I/O
......@@ -869,6 +861,7 @@ config COMEDI_II_PCI20KC
config COMEDI_DAQBOARD2000
tristate "IOtech DAQboard/2000 support"
select COMEDI_8255
default N
---help---
Enable support for the IOtech DAQboard/2000
......@@ -896,6 +889,7 @@ config COMEDI_KE_COUNTER
config COMEDI_CB_PCIDAS64
tristate "MeasurementComputing PCI-DAS 64xx, 60xx, and 4020 support"
select COMEDI_8255
select COMEDI_FC
default N
---help---
......@@ -907,6 +901,7 @@ config COMEDI_CB_PCIDAS64
config COMEDI_CB_PCIDAS
tristate "MeasurementComputing PCI-DAS support"
select COMEDI_8255
select COMEDI_FC
default N
---help---
......@@ -920,6 +915,7 @@ config COMEDI_CB_PCIDAS
config COMEDI_CB_PCIDDA
tristate "MeasurementComputing PCI-DDA series support"
select COMEDI_8255
default N
---help---
Enable support for ComputerBoards/MeasurementComputing PCI-DDA
......@@ -931,6 +927,7 @@ config COMEDI_CB_PCIDDA
config COMEDI_CB_PCIDIO
tristate "MeasurementComputing PCI-DIO series support"
select COMEDI_8255
default N
---help---
Enable support for ComputerBoards/MeasurementComputing PCI-DIO series
......@@ -941,6 +938,7 @@ config COMEDI_CB_PCIDIO
config COMEDI_CB_PCIMDAS
tristate "MeasurementComputing PCIM-DAS1602/16 support"
select COMEDI_8255
default N
---help---
Enable support for ComputerBoards/MeasurementComputing PCI Migration
......@@ -951,6 +949,7 @@ config COMEDI_CB_PCIMDAS
config COMEDI_CB_PCIMDDA
tristate "MeasurementComputing PCIM-DDA06-16 support"
select COMEDI_8255
default N
---help---
Enable support for ComputerBoards/MeasurementComputing PCIM-DDA06-16
......@@ -1026,6 +1025,7 @@ config COMEDI_NI_670X
config COMEDI_NI_PCIDIO
tristate "NI PCI-DIO32HS, PCI-DIO96, PCI-6533, PCI-6503 support"
depends on COMEDI_MITE
select COMEDI_8255
default N
---help---
Enable support for National Instruments PCI-DIO-32HS, PXI-6533,
......@@ -1058,6 +1058,7 @@ config COMEDI_NI_PCIMIO
config COMEDI_RTD520
tristate "Real Time Devices PCI4520/DM7520 support"
select COMEDI_8255
default N
---help---
Enable support for Real Time Devices PCI4520/DM7520
......@@ -1097,7 +1098,7 @@ endif # COMEDI_PCI_DRIVERS
menuconfig COMEDI_PCMCIA_DRIVERS
tristate "Comedi PCMCIA drivers"
depends on COMEDI && PCMCIA && PCCARD
depends on COMEDI && (PCMCIA || PCCARD)
default N
---help---
Enable comedi PCMCIA and PCCARD drivers to be built
......@@ -1142,6 +1143,7 @@ config COMEDI_NI_DAQ_700_CS
config COMEDI_NI_DAQ_DIO24_CS
tristate "NI DAQ-Card DIO-24 PCMCIA support"
depends on COMEDI_NI_COMMON
select COMEDI_8255
default N
---help---
Enable support for the National Instruments PCMCIA DAQ-Card DIO-24
......@@ -1162,8 +1164,8 @@ config COMEDI_NI_LABPC_CS
config COMEDI_NI_MIO_CS
tristate "NI DAQCard E series PCMCIA support"
depends on COMEDI_NI_TIO && COMEDI_NI_COMMON
default N
select COMEDI_FC
default N
---help---
Enable support for the National Instruments PCMCIA DAQCard E series
DAQCard-ai-16xe-50, DAQCard-ai-16e-4, DAQCard-6062E, DAQCard-6024E
......@@ -1265,7 +1267,8 @@ config COMEDI_MITE
config COMEDI_NI_TIO
tristate "NI general purpose counter support"
select COMEDI_MITE
depends on COMEDI_MITE
select COMEDI_8255
default N
---help---
Enable support for National Instruments general purpose counters.
......@@ -1278,6 +1281,8 @@ config COMEDI_NI_TIO
config COMEDI_NI_LABPC
tristate "NI Lab-PC and compatibles ISA and PCI support"
depends on COMEDI_MITE
select COMEDI_8255
select COMEDI_FC
default N
---help---
......@@ -1291,8 +1296,40 @@ config COMEDI_NI_LABPC
endif # COMEDI_NI_COMMON
config COMEDI_8255
tristate "Generic 8255 support"
depends on COMEDI
default N
---help---
Enable generic 8255 support.
You should enable compilation this driver if you plan to use a board
that has an 8255 chip. For multifunction boards, the main driver will
configure the 8255 subdevice automatically.
Note that most PCI 8255 boards do NOT work with this driver, and
need a separate driver as a wrapper.
To compile this driver as a module, choose M here: the module will be
called 8255.
config COMEDI_DAS08
tristate "DAS-08 compatible support"
depends on COMEDI
select COMEDI_8255
default N
---help---
Enable support for DAS08 and compatible ISA, PC/104 and PCI cards.
Note that PCMCIA DAS08 cards are not directly supported by this
driver, and need a separate driver as a wrapper.
To compile this driver as a module, choose M here: the module will be
called das08.
config COMEDI_FC
tristate "Comedi shared functions for low-level driver support"
depends on COMEDI
default N
---help---
Enable support for shared functions for low-level drivers.
......
......@@ -83,7 +83,7 @@ static int do_subdinfo_ioctl(struct comedi_device *dev,
static int do_chaninfo_ioctl(struct comedi_device *dev,
struct comedi_chaninfo __user *arg);
static int do_bufinfo_ioctl(struct comedi_device *dev,
struct comedi_bufinfo __user *arg);
struct comedi_bufinfo __user *arg, void *file);
static int do_cmd_ioctl(struct comedi_device *dev,
struct comedi_cmd __user *arg, void *file);
static int do_lock_ioctl(struct comedi_device *dev, unsigned int arg,
......@@ -169,7 +169,8 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
break;
case COMEDI_BUFINFO:
rc = do_bufinfo_ioctl(dev,
(struct comedi_bufinfo __user *)arg);
(struct comedi_bufinfo __user *)arg,
file);
break;
case COMEDI_LOCK:
rc = do_lock_ioctl(dev, arg, file);
......@@ -563,7 +564,7 @@ static int do_chaninfo_ioctl(struct comedi_device *dev,
*/
static int do_bufinfo_ioctl(struct comedi_device *dev,
struct comedi_bufinfo __user *arg)
struct comedi_bufinfo __user *arg, void *file)
{
struct comedi_bufinfo bi;
struct comedi_subdevice *s;
......@@ -576,6 +577,10 @@ static int do_bufinfo_ioctl(struct comedi_device *dev,
return -EINVAL;
s = dev->subdevices + bi.subdevice;
if (s->lock && s->lock != file)
return -EACCES;
async = s->async;
if (!async) {
......@@ -584,8 +589,17 @@ static int do_bufinfo_ioctl(struct comedi_device *dev,
bi.buf_read_ptr = 0;
bi.buf_write_count = 0;
bi.buf_read_count = 0;
bi.bytes_read = 0;
bi.bytes_written = 0;
goto copyback;
}
if (!s->busy) {
bi.bytes_read = 0;
bi.bytes_written = 0;
goto copyback_position;
}
if (s->busy != file)
return -EACCES;
if (bi.bytes_read && (s->subdev_flags & SDF_CMD_READ)) {
bi.bytes_read = comedi_buf_read_alloc(async, bi.bytes_read);
......@@ -604,6 +618,7 @@ static int do_bufinfo_ioctl(struct comedi_device *dev,
comedi_buf_write_free(async, bi.bytes_written);
}
copyback_position:
bi.buf_write_count = async->buf_write_count;
bi.buf_write_ptr = async->buf_write_ptr;
bi.buf_read_count = async->buf_read_count;
......@@ -1576,6 +1591,19 @@ static ssize_t comedi_write(struct file *file, const char __user *buf,
while (nbytes > 0 && !retval) {
set_current_state(TASK_INTERRUPTIBLE);
if (!(comedi_get_subdevice_runflags(s) & SRF_RUNNING)) {
if (count == 0) {
if (comedi_get_subdevice_runflags(s) &
SRF_ERROR) {
retval = -EPIPE;
} else {
retval = 0;
}
do_become_nonbusy(dev, s);
}
break;
}
n = nbytes;
m = n;
......@@ -1588,16 +1616,6 @@ static ssize_t comedi_write(struct file *file, const char __user *buf,
n = m;
if (n == 0) {
if (!(comedi_get_subdevice_runflags(s) & SRF_RUNNING)) {
if (comedi_get_subdevice_runflags(s) &
SRF_ERROR) {
retval = -EPIPE;
} else {
retval = 0;
}
do_become_nonbusy(dev, s);
break;
}
if (file->f_flags & O_NONBLOCK) {
retval = -EAGAIN;
break;
......
......@@ -12,7 +12,6 @@ obj-$(CONFIG_COMEDI_SERIAL2002) += serial2002.o
obj-$(CONFIG_COMEDI_SKEL) += skel.o
# Comedi ISA drivers
obj-$(CONFIG_COMEDI_8255) += 8255.o
obj-$(CONFIG_COMEDI_ACL7225B) += acl7225b.o
obj-$(CONFIG_COMEDI_PCL711) += pcl711.o
obj-$(CONFIG_COMEDI_PCL724) += pcl724.o
......@@ -26,7 +25,6 @@ obj-$(CONFIG_COMEDI_PCM3724) += pcm3724.o
obj-$(CONFIG_COMEDI_PCM3730) += pcm3730.o
obj-$(CONFIG_COMEDI_RTI800) += rti800.o
obj-$(CONFIG_COMEDI_RTI802) += rti802.o
obj-$(CONFIG_COMEDI_DAS08) += das08.o
obj-$(CONFIG_COMEDI_DAS16M1) += das16m1.o
obj-$(CONFIG_COMEDI_DAS16) += das16.o
obj-$(CONFIG_COMEDI_DAS800) += das800.o
......@@ -135,4 +133,6 @@ obj-$(CONFIG_COMEDI_NI_TIO) += ni_tio.o
obj-$(CONFIG_COMEDI_NI_TIO) += ni_tiocmd.o
obj-$(CONFIG_COMEDI_NI_LABPC) += ni_labpc.o
obj-$(CONFIG_COMEDI_8255) += 8255.o
obj-$(CONFIG_COMEDI_DAS08) += das08.o
obj-$(CONFIG_COMEDI_FC) += comedi_fc.o
......@@ -68,6 +68,10 @@ You should also find the complete GPL in the COPYING file accompanying this sour
#include "addi_common.h"
#include "addi_amcc_s5933.h"
#ifndef ADDIDATA_DRIVER_NAME
#define ADDIDATA_DRIVER_NAME "addi_common"
#endif
/* Update-0.7.57->0.7.68MODULE_AUTHOR("ADDI-DATA GmbH <info@addi-data.com>"); */
/* Update-0.7.57->0.7.68MODULE_DESCRIPTION("Comedi ADDI-DATA module"); */
/* Update-0.7.57->0.7.68MODULE_LICENSE("GPL"); */
......@@ -2528,7 +2532,7 @@ static const struct addi_board boardtypes[] = {
#define n_boardtypes (sizeof(boardtypes)/sizeof(struct addi_board))
static struct comedi_driver driver_addi = {
.driver_name = "addi_common",
.driver_name = ADDIDATA_DRIVER_NAME,
.module = THIS_MODULE,
.attach = i_ADDI_Attach,
.detach = i_ADDI_Detach,
......@@ -2570,10 +2574,6 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it)
struct pcilst_struct *card = NULL;
unsigned char pci_bus, pci_slot, pci_func;
int i_Dma = 0;
static char c_Identifier[150];
sprintf(c_Identifier, "Addi-Data GmbH Comedi %s",
this_board->pc_DriverName);
ret = alloc_private(dev, sizeof(struct addi_private));
if (ret < 0)
......@@ -2583,7 +2583,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it)
v_pci_card_list_init(this_board->i_VendorId, 1); /* 1 for displaying the list.. */
pci_list_builded = 1;
}
/* printk("comedi%d: addi_common: board=%s",dev->minor,this_board->pc_DriverName); */
/* printk("comedi%d: "ADDIDATA_DRIVER_NAME": board=%s",dev->minor,this_board->pc_DriverName); */
if ((this_board->i_Dma) && (it->options[2] == 0)) {
i_Dma = 1;
......@@ -2648,7 +2648,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it)
if (irq > 0) {
if (request_irq(irq, v_ADDI_Interrupt, IRQF_SHARED,
c_Identifier, dev) < 0) {
this_board->pc_DriverName, dev) < 0) {
printk(", unable to allocate IRQ %u, DISABLING IT",
irq);
irq = 0; /* Can't use IRQ */
......
......@@ -2,4 +2,6 @@
#define ADDIDATA_WATCHDOG 2 /* Or shold it be something else */
#define ADDIDATA_DRIVER_NAME "addi_apci_035"
#include "addi-data/addi_common.c"
#define CONFIG_APCI_1032 1
#define ADDIDATA_DRIVER_NAME "addi_apci_1032"
#include "addi-data/addi_common.c"
#define CONFIG_APCI_1500 1
#define ADDIDATA_DRIVER_NAME "addi_apci_1500"
#include "addi-data/addi_common.c"
#define CONFIG_APCI_1516 1
#define ADDIDATA_DRIVER_NAME "addi_apci_1516"
#include "addi-data/addi_common.c"
#define CONFIG_APCI_1564 1
#define ADDIDATA_DRIVER_NAME "addi_apci_1564"
#include "addi-data/addi_common.c"
#define CONFIG_APCI_16XX 1
#define ADDIDATA_DRIVER_NAME "addi_apci_16xx"
#include "addi-data/addi_common.c"
#define CONFIG_APCI_1710 1
#define ADDIDATA_DRIVER_NAME "addi_apci_1710"
#include "addi-data/addi_common.c"
#define CONFIG_APCI_2016 1
#define ADDIDATA_DRIVER_NAME "addi_apci_2016"
#include "addi-data/addi_common.c"
#define CONFIG_APCI_2032 1
#define ADDIDATA_DRIVER_NAME "addi_apci_2032"
#include "addi-data/addi_common.c"
#define CONFIG_APCI_2200 1
#define ADDIDATA_DRIVER_NAME "addi_apci_2200"
#include "addi-data/addi_common.c"
#define CONFIG_APCI_3001 1
#define ADDIDATA_DRIVER_NAME "addi_apci_3001"
#include "addi-data/addi_common.c"
#define CONFIG_APCI_3120 1
#define ADDIDATA_DRIVER_NAME "addi_apci_3120"
#include "addi-data/addi_common.c"
#define CONFIG_APCI_3200 1
#define ADDIDATA_DRIVER_NAME "addi_apci_3200"
#include "addi-data/addi_common.c"
#define CONFIG_APCI_3300 1
#define ADDIDATA_DRIVER_NAME "addi_apci_3300"
#include "addi-data/addi_common.c"
#define CONFIG_APCI_3501 1
#define ADDIDATA_DRIVER_NAME "addi_apci_3501"
#include "addi-data/addi_common.c"
#define CONFIG_APCI_3XXX 1
#define ADDIDATA_DRIVER_NAME "addi_apci_3xxx"
#include "addi-data/addi_common.c"
......@@ -7,17 +7,17 @@
*/
/*
Driver: adv_pci_dio
Description: Advantech PCI-1730, PCI-1733, PCI-1734, PCI-1736UP,
PCI-1750, PCI-1751, PCI-1752, PCI-1753/E, PCI-1754,
PCI-1756, PCI-1762
Description: Advantech PCI-1730, PCI-1733, PCI-1734, PCI-1735U,
PCI-1736UP, PCI-1750, PCI-1751, PCI-1752, PCI-1753/E,
PCI-1754, PCI-1756, PCI-1762
Author: Michal Dobes <dobes@tesnet.cz>
Devices: [Advantech] PCI-1730 (adv_pci_dio), PCI-1733,
PCI-1734, PCI-1736UP, PCI-1750,
PCI-1734, PCI-1735U, PCI-1736UP, PCI-1750,
PCI-1751, PCI-1752, PCI-1753,
PCI-1753+PCI-1753E, PCI-1754, PCI-1756,
PCI-1760, PCI-1762
Status: untested
Updated: Mon, 14 Apr 2008 10:43:08 +0100
Updated: Tue, 04 May 2010 13:00:00 +0000
This driver supports now only insn interface for DI/DO/DIO.
......@@ -35,6 +35,7 @@ Configuration options:
#include "comedi_pci.h"
#include "8255.h"
#include "8253.h"
#undef PCI_DIO_EXTDEBUG /* if defined, enable extensive debug logging */
......@@ -49,7 +50,7 @@ Configuration options:
/* hardware types of the cards */
enum hw_cards_id {
TYPE_PCI1730, TYPE_PCI1733, TYPE_PCI1734, TYPE_PCI1736,
TYPE_PCI1730, TYPE_PCI1733, TYPE_PCI1734, TYPE_PCI1735, TYPE_PCI1736,
TYPE_PCI1750,
TYPE_PCI1751,
TYPE_PCI1752,
......@@ -67,7 +68,10 @@ enum hw_io_access {
#define MAX_DI_SUBDEVS 2 /* max number of DI subdevices per card */
#define MAX_DO_SUBDEVS 2 /* max number of DO subdevices per card */
#define MAX_DIO_SUBDEVG 2 /* max number of DIO subdevices group per card */
#define MAX_8254_SUBDEVS 1 /* max number of 8254 counter subdevs per card */
/* (could be more than one 8254 per subdevice) */
#define SIZE_8254 4 /* 8254 IO space length */
#define SIZE_8255 4 /* 8255 IO space length */
#define PCIDIO_MAINREG 2 /* main I/O region for all Advantech cards? */
......@@ -85,6 +89,12 @@ enum hw_io_access {
#define PCI1734_IDO 0 /* W: Isolated digital output 0-31 */
#define PCI173x_BOARDID 4 /* R: Board I/D switch for 1730/3/4 */
/* Advantech PCI-1735U */
#define PCI1735_DI 0 /* R: Digital input 0-31 */
#define PCI1735_DO 0 /* W: Digital output 0-31 */
#define PCI1735_C8254 4 /* R/W: 8254 counter */
#define PCI1735_BOARDID 8 /* R: Board I/D switch for 1735U */
/* Advantech PCI-1736UP */
#define PCI1736_IDI 0 /* R: Isolated digital input 0-15 */
#define PCI1736_IDO 0 /* W: Isolated digital output 0-15 */
......@@ -192,7 +202,8 @@ static int pci_dio_detach(struct comedi_device *dev);
struct diosubd_data {
int chans; /* num of chans */
int addr; /* PCI address ofset */
int regs; /* number of registers to read or 8255 subdevices */
int regs; /* number of registers to read or 8255
subdevices or 8254 chips */
unsigned int specflags; /* addon subdevice flags */
};
......@@ -206,6 +217,7 @@ struct dio_boardtype {
struct diosubd_data sdo[MAX_DO_SUBDEVS]; /* DO chans */
struct diosubd_data sdio[MAX_DIO_SUBDEVG]; /* DIO 8255 chans */
struct diosubd_data boardid; /* card supports board ID switch */
struct diosubd_data s8254[MAX_8254_SUBDEVS]; /* 8254 subdevices */
enum hw_io_access io_access;
};
......@@ -214,6 +226,7 @@ static DEFINE_PCI_DEVICE_TABLE(pci_dio_pci_table) = {
PCI_VENDOR_ID_ADVANTECH, 0x1730, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
PCI_VENDOR_ID_ADVANTECH, 0x1733, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
PCI_VENDOR_ID_ADVANTECH, 0x1734, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
PCI_VENDOR_ID_ADVANTECH, 0x1735, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
PCI_VENDOR_ID_ADVANTECH, 0x1736, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
PCI_VENDOR_ID_ADVANTECH, 0x1750, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
PCI_VENDOR_ID_ADVANTECH, 0x1751, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
......@@ -235,14 +248,15 @@ static const struct dio_boardtype boardtypes[] = {
{{16, PCI1730_DO, 2, 0}, {16, PCI1730_IDO, 2, 0}},
{{0, 0, 0, 0}, {0, 0, 0, 0}},
{4, PCI173x_BOARDID, 1, SDF_INTERNAL},
IO_8b,
},
{{0, 0, 0, 0}},
IO_8b},
{"pci1733", PCI_VENDOR_ID_ADVANTECH, 0x1733, PCIDIO_MAINREG,
TYPE_PCI1733,
{{0, 0, 0, 0}, {32, PCI1733_IDI, 4, 0}},
{{0, 0, 0, 0}, {0, 0, 0, 0}},
{{0, 0, 0, 0}, {0, 0, 0, 0}},
{4, PCI173x_BOARDID, 1, SDF_INTERNAL},
{{0, 0, 0, 0}},
IO_8b},
{"pci1734", PCI_VENDOR_ID_ADVANTECH, 0x1734, PCIDIO_MAINREG,
TYPE_PCI1734,
......@@ -250,6 +264,15 @@ static const struct dio_boardtype boardtypes[] = {
{{0, 0, 0, 0}, {32, PCI1734_IDO, 4, 0}},
{{0, 0, 0, 0}, {0, 0, 0, 0}},
{4, PCI173x_BOARDID, 1, SDF_INTERNAL},
{{0, 0, 0, 0}},
IO_8b},
{"pci1735", PCI_VENDOR_ID_ADVANTECH, 0x1735, PCIDIO_MAINREG,
TYPE_PCI1735,
{{32, PCI1735_DI, 4, 0}, {0, 0, 0, 0}},
{{32, PCI1735_DO, 4, 0}, {0, 0, 0, 0}},
{{0, 0, 0, 0}, {0, 0, 0, 0}},
{ 4, PCI1735_BOARDID, 1, SDF_INTERNAL},
{{3, PCI1735_C8254, 1, 0}},
IO_8b},
{"pci1736", PCI_VENDOR_ID_ADVANTECH, 0x1736, PCI1736_MAINREG,
TYPE_PCI1736,
......@@ -257,14 +280,15 @@ static const struct dio_boardtype boardtypes[] = {
{{0, 0, 0, 0}, {16, PCI1736_IDO, 2, 0}},
{{0, 0, 0, 0}, {0, 0, 0, 0}},
{4, PCI1736_BOARDID, 1, SDF_INTERNAL},
IO_8b,
},
{{0, 0, 0, 0}},
IO_8b},
{"pci1750", PCI_VENDOR_ID_ADVANTECH, 0x1750, PCIDIO_MAINREG,
TYPE_PCI1750,
{{0, 0, 0, 0}, {16, PCI1750_IDI, 2, 0}},
{{0, 0, 0, 0}, {16, PCI1750_IDO, 2, 0}},
{{0, 0, 0, 0}, {0, 0, 0, 0}},
{0, 0, 0, 0},
{{0, 0, 0, 0}},
IO_8b},
{"pci1751", PCI_VENDOR_ID_ADVANTECH, 0x1751, PCIDIO_MAINREG,
TYPE_PCI1751,
......@@ -272,6 +296,7 @@ static const struct dio_boardtype boardtypes[] = {
{{0, 0, 0, 0}, {0, 0, 0, 0}},
{{48, PCI1751_DIO, 2, 0}, {0, 0, 0, 0}},
{0, 0, 0, 0},
{{0, 0, 0, 0}},
IO_8b},
{"pci1752", PCI_VENDOR_ID_ADVANTECH, 0x1752, PCIDIO_MAINREG,
TYPE_PCI1752,
......@@ -279,6 +304,7 @@ static const struct dio_boardtype boardtypes[] = {
{{32, PCI1752_IDO, 2, 0}, {32, PCI1752_IDO2, 2, 0}},
{{0, 0, 0, 0}, {0, 0, 0, 0}},
{4, PCI175x_BOARDID, 1, SDF_INTERNAL},
{{0, 0, 0, 0}},
IO_16b},
{"pci1753", PCI_VENDOR_ID_ADVANTECH, 0x1753, PCIDIO_MAINREG,
TYPE_PCI1753,
......@@ -286,6 +312,7 @@ static const struct dio_boardtype boardtypes[] = {
{{0, 0, 0, 0}, {0, 0, 0, 0}},
{{96, PCI1753_DIO, 4, 0}, {0, 0, 0, 0}},
{0, 0, 0, 0},
{{0, 0, 0, 0}},
IO_8b},
{"pci1753e", PCI_VENDOR_ID_ADVANTECH, 0x1753, PCIDIO_MAINREG,
TYPE_PCI1753E,
......@@ -293,6 +320,7 @@ static const struct dio_boardtype boardtypes[] = {
{{0, 0, 0, 0}, {0, 0, 0, 0}},
{{96, PCI1753_DIO, 4, 0}, {96, PCI1753E_DIO, 4, 0}},
{0, 0, 0, 0},
{{0, 0, 0, 0}},
IO_8b},
{"pci1754", PCI_VENDOR_ID_ADVANTECH, 0x1754, PCIDIO_MAINREG,
TYPE_PCI1754,
......@@ -300,6 +328,7 @@ static const struct dio_boardtype boardtypes[] = {
{{0, 0, 0, 0}, {0, 0, 0, 0}},
{{0, 0, 0, 0}, {0, 0, 0, 0}},
{4, PCI175x_BOARDID, 1, SDF_INTERNAL},
{{0, 0, 0, 0}},
IO_16b},
{"pci1756", PCI_VENDOR_ID_ADVANTECH, 0x1756, PCIDIO_MAINREG,
TYPE_PCI1756,
......@@ -307,6 +336,7 @@ static const struct dio_boardtype boardtypes[] = {
{{0, 0, 0, 0}, {32, PCI1756_IDO, 2, 0}},
{{0, 0, 0, 0}, {0, 0, 0, 0}},
{4, PCI175x_BOARDID, 1, SDF_INTERNAL},
{{0, 0, 0, 0}},
IO_16b},
{"pci1760", PCI_VENDOR_ID_ADVANTECH, 0x1760, 0,
TYPE_PCI1760,
......@@ -314,6 +344,7 @@ static const struct dio_boardtype boardtypes[] = {
{{0, 0, 0, 0}, {0, 0, 0, 0}},
{{0, 0, 0, 0}, {0, 0, 0, 0}},
{0, 0, 0, 0},
{{0, 0, 0, 0}},
IO_8b},
{"pci1762", PCI_VENDOR_ID_ADVANTECH, 0x1762, PCIDIO_MAINREG,
TYPE_PCI1762,
......@@ -321,6 +352,7 @@ static const struct dio_boardtype boardtypes[] = {
{{0, 0, 0, 0}, {16, PCI1762_RO, 1, 0}},
{{0, 0, 0, 0}, {0, 0, 0, 0}},
{4, PCI1762_BOARDID, 1, SDF_INTERNAL},
{{0, 0, 0, 0}},
IO_16b}
};
......@@ -437,6 +469,83 @@ static int pci_dio_insn_bits_do_w(struct comedi_device *dev,
return 2;
}
/*
==============================================================================
*/
static int pci_8254_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
const struct diosubd_data *d = (const struct diosubd_data *)s->private;
unsigned int chan, chip, chipchan;
unsigned long flags;
chan = CR_CHAN(insn->chanspec); /* channel on subdevice */
chip = chan / 3; /* chip on subdevice */
chipchan = chan - (3 * chip); /* channel on chip on subdevice */
spin_lock_irqsave(&s->spin_lock, flags);
data[0] = i8254_read(dev->iobase + d->addr + (SIZE_8254 * chip),
0, chipchan);
spin_unlock_irqrestore(&s->spin_lock, flags);
return 1;
}
/*
==============================================================================
*/
static int pci_8254_insn_write(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
const struct diosubd_data *d = (const struct diosubd_data *)s->private;
unsigned int chan, chip, chipchan;
unsigned long flags;
chan = CR_CHAN(insn->chanspec); /* channel on subdevice */
chip = chan / 3; /* chip on subdevice */
chipchan = chan - (3 * chip); /* channel on chip on subdevice */
spin_lock_irqsave(&s->spin_lock, flags);
i8254_write(dev->iobase + d->addr + (SIZE_8254 * chip),
0, chipchan, data[0]);
spin_unlock_irqrestore(&s->spin_lock, flags);
return 1;
}
/*
==============================================================================
*/
static int pci_8254_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
const struct diosubd_data *d = (const struct diosubd_data *)s->private;
unsigned int chan, chip, chipchan;
unsigned long iobase;
int ret = 0;
unsigned long flags;
chan = CR_CHAN(insn->chanspec); /* channel on subdevice */
chip = chan / 3; /* chip on subdevice */
chipchan = chan - (3 * chip); /* channel on chip on subdevice */
iobase = dev->iobase + d->addr + (SIZE_8254 * chip);
spin_lock_irqsave(&s->spin_lock, flags);
switch (data[0]) {
case INSN_CONFIG_SET_COUNTER_MODE:
ret = i8254_set_mode(iobase, 0, chipchan, data[1]);
if (ret < 0)
ret = -EINVAL;
break;
case INSN_CONFIG_8254_READ_STATUS:
data[1] = i8254_status(iobase, 0, chipchan);
break;
default:
ret = -EINVAL;
break;
}
spin_unlock_irqrestore(&s->spin_lock, flags);
return ret < 0 ? ret : insn->n;
}
/*
==============================================================================
*/
......@@ -708,6 +817,15 @@ static int pci_dio_reset(struct comedi_device *dev)
outb(0, dev->iobase + PCI1734_IDO + 2);
outb(0, dev->iobase + PCI1734_IDO + 3);
break;
case TYPE_PCI1735:
outb(0, dev->iobase + PCI1735_DO); /* clear outputs */
outb(0, dev->iobase + PCI1735_DO + 1);
outb(0, dev->iobase + PCI1735_DO + 2);
outb(0, dev->iobase + PCI1735_DO + 3);
i8254_set_mode(dev->iobase + PCI1735_C8254, 0, 0, I8254_MODE0);
i8254_set_mode(dev->iobase + PCI1735_C8254, 0, 1, I8254_MODE0);
i8254_set_mode(dev->iobase + PCI1735_C8254, 0, 2, I8254_MODE0);
break;
case TYPE_PCI1736:
outb(0, dev->iobase + PCI1736_IDO);
......@@ -874,6 +992,26 @@ static int pci_dio_add_do(struct comedi_device *dev, struct comedi_subdevice *s,
return 0;
}
/*
==============================================================================
*/
static int pci_dio_add_8254(struct comedi_device *dev,
struct comedi_subdevice * s,
const struct diosubd_data *d, int subdev)
{
s->type = COMEDI_SUBD_COUNTER;
s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
s->n_chan = d->chans;
s->maxdata = 65535;
s->len_chanlist = d->chans;
s->insn_read = pci_8254_insn_read;
s->insn_write = pci_8254_insn_write;
s->insn_config = pci_8254_insn_config;
s->private = (void *)d;
return 0;
}
/*
==============================================================================
*/
......@@ -979,6 +1117,9 @@ static int pci_dio_attach(struct comedi_device *dev,
n_subdevices += this_board->sdio[i].regs;
if (this_board->boardid.chans)
n_subdevices++;
for (i = 0; i < MAX_8254_SUBDEVS; i++)
if (this_board->s8254[i].chans)
n_subdevices++;
}
ret = alloc_subdevices(dev, n_subdevices);
......@@ -1022,6 +1163,13 @@ static int pci_dio_attach(struct comedi_device *dev,
subdev++;
}
for (i = 0; i < MAX_8254_SUBDEVS; i++)
if (this_board->s8254[i].chans) {
s = dev->subdevices + subdev;
pci_dio_add_8254(dev, s, &this_board->s8254[i], subdev);
subdev++;
}
if (this_board->cardtype == TYPE_PCI1760)
pci1760_attach(dev, it);
......@@ -1067,6 +1215,16 @@ static int pci_dio_detach(struct comedi_device *dev)
}
}
if (this_board->boardid.chans) {
subdev++;
}
for (i = 0; i < MAX_8254_SUBDEVS; i++) {
if (this_board->s8254[i].chans) {
subdev++;
}
}
for (i = 0; i < dev->n_subdevices; i++) {
s = dev->subdevices + i;
s->private = NULL;
......
......@@ -460,6 +460,7 @@ struct dio200_subdev_8254 {
int has_clk_gat_sce;
unsigned clock_src[3]; /* Current clock sources */
unsigned gate_src[3]; /* Current gate sources */
spinlock_t spinlock;
};
struct dio200_subdev_intr {
......@@ -1042,8 +1043,11 @@ dio200_subdev_8254_read(struct comedi_device *dev, struct comedi_subdevice *s,
{
struct dio200_subdev_8254 *subpriv = s->private;
int chan = CR_CHAN(insn->chanspec);
unsigned long flags;
spin_lock_irqsave(&subpriv->spinlock, flags);
data[0] = i8254_read(subpriv->iobase, 0, chan);
spin_unlock_irqrestore(&subpriv->spinlock, flags);
return 1;
}
......@@ -1057,8 +1061,11 @@ dio200_subdev_8254_write(struct comedi_device *dev, struct comedi_subdevice *s,
{
struct dio200_subdev_8254 *subpriv = s->private;
int chan = CR_CHAN(insn->chanspec);
unsigned long flags;
spin_lock_irqsave(&subpriv->spinlock, flags);
i8254_write(subpriv->iobase, 0, chan, data[0]);
spin_unlock_irqrestore(&subpriv->spinlock, flags);
return 1;
}
......@@ -1151,14 +1158,16 @@ dio200_subdev_8254_config(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
struct dio200_subdev_8254 *subpriv = s->private;
int ret;
int ret = 0;
int chan = CR_CHAN(insn->chanspec);
unsigned long flags;
spin_lock_irqsave(&subpriv->spinlock, flags);
switch (data[0]) {
case INSN_CONFIG_SET_COUNTER_MODE:
ret = i8254_set_mode(subpriv->iobase, 0, chan, data[1]);
if (ret < 0)
return -EINVAL;
ret = -EINVAL;
break;
case INSN_CONFIG_8254_READ_STATUS:
data[1] = i8254_status(subpriv->iobase, 0, chan);
......@@ -1166,30 +1175,35 @@ dio200_subdev_8254_config(struct comedi_device *dev, struct comedi_subdevice *s,
case INSN_CONFIG_SET_GATE_SRC:
ret = dio200_set_gate_src(subpriv, chan, data[2]);
if (ret < 0)
return -EINVAL;
ret = -EINVAL;
break;
case INSN_CONFIG_GET_GATE_SRC:
ret = dio200_get_gate_src(subpriv, chan);
if (ret < 0)
return -EINVAL;
if (ret < 0) {
ret = -EINVAL;
break;
}
data[2] = ret;
break;
case INSN_CONFIG_SET_CLOCK_SRC:
ret = dio200_set_clock_src(subpriv, chan, data[1]);
if (ret < 0)
return -EINVAL;
ret = -EINVAL;
break;
case INSN_CONFIG_GET_CLOCK_SRC:
ret = dio200_get_clock_src(subpriv, chan, &data[2]);
if (ret < 0)
return -EINVAL;
if (ret < 0) {
ret = -EINVAL;
break;
}
data[1] = ret;
break;
default:
return -EINVAL;
ret = -EINVAL;
break;
}
return insn->n;
spin_unlock_irqrestore(&subpriv->spinlock, flags);
return ret < 0 ? ret : insn->n;
}
/*
......@@ -1222,6 +1236,7 @@ dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s,
s->insn_write = dio200_subdev_8254_write;
s->insn_config = dio200_subdev_8254_config;
spin_lock_init(&subpriv->spinlock);
subpriv->iobase = offset + iobase;
subpriv->has_clk_gat_sce = has_clk_gat_sce;
if (has_clk_gat_sce) {
......
......@@ -123,7 +123,7 @@ static const struct ni_board_struct ni_boards[] = {
.adbits = 12,
.ai_fifo_depth = 1024,
.alwaysdither = 0,
.gainlkup = ai_gain_16,
.gainlkup = ai_gain_4,
.ai_speed = 5000,
.n_aochan = 2,
.aobits = 12,
......
......@@ -351,8 +351,7 @@ static int usbdux_ai_stop(struct usbduxsub *this_usbduxsub, int do_unlink)
int ret = 0;
if (!this_usbduxsub) {
dev_err(&this_usbduxsub->interface->dev,
"comedi?: usbdux_ai_stop: this_usbduxsub=NULL!\n");
pr_err("comedi?: usbdux_ai_stop: this_usbduxsub=NULL!\n");
return -EFAULT;
}
dev_dbg(&this_usbduxsub->interface->dev, "comedi: usbdux_ai_stop\n");
......
......@@ -176,9 +176,7 @@ int allocator_free_dma(unsigned long address)
prev = ptr; ptr = ptr->next;
if (!ptr) {
printk(KERN_ERR ALL_MSG
"free_dma(0x%08lx) but add. not allocated\n",
ptr->address);
pr_err(ALL_MSG "free_dma but add. not allocated\n");
return -EINVAL;
}
PDEBUGG("freeing: %08lx (%li) next %08lx\n", ptr->address, ptr->size,
......
......@@ -62,9 +62,8 @@ inline int find_type_by_name(const char *name, const char *type)
1) != 0) {
filename = malloc(strlen(iio_dir)
+ strlen(type)
+ 1
+ numstrlen
+ 1);
+ 6);
if (filename == NULL)
return -ENOMEM;
sprintf(filename, "%s%s%d/name",
......
......@@ -20,7 +20,7 @@ static inline int __iio_allocate_sw_ring_buffer(struct iio_sw_ring_buffer *ring,
if ((length == 0) || (bytes_per_datum == 0))
return -EINVAL;
__iio_update_ring_buffer(&ring->buf, bytes_per_datum, length);
ring->data = kmalloc(length*ring->buf.bpd, GFP_KERNEL);
ring->data = kmalloc(length*ring->buf.bpd, GFP_ATOMIC);
ring->read_p = NULL;
ring->write_p = NULL;
ring->last_written_p = NULL;
......
config TOUCHSCREEN_INTEL_MID
tristate "Intel MID platform resistive touchscreen"
depends on INTEL_SCU_IPC
default y
help
Say Y here if you have a Intel MID based touchscreen
If unsure, say N.
obj-$(CONFIG_TOUCHSCREEN_INTEL_MID) := intel_mid_touch.o
- Move the driver to not think it is SPI (requires fixing some of the SFI
and firmware side)
此差异已折叠。
config MSM_STAGING
tristate "MSM Frame Buffer Support"
depends on FB && ARCH_MSM && !FB_MSM
select FB_BACKLIGHT if FB_MSM_BACKLIGHT
select NEW_LEDS
select LEDS_CLASS
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
---help---
Support for MSM Framebuffer.
if MSM_STAGING
config FB_MSM_LCDC_HW
bool
default n
choice
prompt "MDP HW version"
default FB_MSM_MDP31
config FB_MSM_MDP31
select FB_MSM_LCDC_HW
bool "MDP HW ver3.1"
---help---
Support for MSM MDP HW revision 3.1
Say Y here if this is msm8x50 variant platform.
endchoice
config FB_MSM_LCDC
bool
default n
config FB_MSM_TVOUT
bool
default n
config FB_MSM_LCDC_PANEL
bool
select FB_MSM_LCDC
default n
config FB_MSM_LCDC_PRISM_WVGA
bool
select FB_MSM_LCDC_PANEL
default n
config FB_MSM_LCDC_ST1_WXGA
bool
select FB_MSM_LCDC_PANEL
default n
config FB_MSM_LCDC_ST15_WXGA
bool
select FB_MSM_LCDC_PANEL
default n
config FB_MSM_LCDC_WXGA
bool
select FB_MSM_LCDC_PANEL
default n
choice
prompt "LCD Panel"
default FB_MSM_LCDC_ST15_PANEL
config FB_MSM_LCDC_PRISM_WVGA_PANEL
depends on FB_MSM_LCDC_HW
bool "LCDC Prism WVGA Panel"
select FB_MSM_LCDC_PRISM_WVGA
---help---
Support for LCDC Prism WVGA (800x480) panel
config FB_MSM_LCDC_ST15_PANEL
depends on FB_MSM_LCDC_HW
bool "LCDC ST1.5 Panel"
select FB_MSM_LCDC_ST15_WXGA
---help---
Support for ST1.5 WXGA (1366x768) panel
config FB_MSM_PANEL_NONE
bool "NONE"
---help---
This will disable LCD panel
endchoice
choice
prompt "Secondary LCD Panel"
depends on FB_MSM_MDP31
default FB_MSM_SECONDARY_PANEL_NONE
config FB_MSM_SECONDARY_PANEL_NONE
bool "NONE"
---help---
No secondary panel
endchoice
config FB_MSM_TVOUT_NTSC
bool
select FB_MSM_TVOUT
default n
config FB_MSM_TVOUT_PAL
bool
select FB_MSM_TVOUT
default n
choice
depends on (FB_MSM_MDP22 || FB_MSM_MDP31)
prompt "TVOut Region"
default FB_MSM_TVOUT_NTSC_M
config FB_MSM_TVOUT_NTSC_M
bool "NTSC M"
select FB_MSM_TVOUT_NTSC
---help---
Support for NTSC M region (North American and Korea)
config FB_MSM_TVOUT_NONE
bool "NONE"
---help---
This will disable TV Out functionality.
endchoice
config PMEM_KERNEL_SIZE
int "PMEM for kernel components (in MB)"
default 2
depends on ARCH_QSD8X50
help
Configures the amount of PMEM for use by kernel components
(in MB; minimum 2MB)
endif
obj-y := msm_fb.o staging-devices.o memory.o
obj-$(CONFIG_FB_MSM_LOGO) += logo.o
obj-$(CONFIG_FB_BACKLIGHT) += msm_fb_bl.o
# MDP
obj-y += mdp.o
ifeq ($(CONFIG_FB_MSM_MDP40),y)
obj-y += mdp4_util.o
obj-$(CONFIG_DEBUG_FS) += mdp4_debugfs.o
else
obj-y += mdp_hw_init.o
obj-y += mdp_ppp.o
ifeq ($(CONFIG_FB_MSM_MDP31),y)
obj-y += mdp_ppp_v31.o
obj-$(CONFIG_MDP_PPP_ASYNC_OP) += mdp_ppp_dq.o
else
obj-y += mdp_ppp_v20.o
endif
endif
ifeq ($(CONFIG_FB_MSM_OVERLAY),y)
obj-y += mdp4_overlay.o
obj-y += mdp4_overlay_lcdc.o
obj-y += mdp4_overlay_mddi.o
else
obj-y += mdp_dma_lcdc.o
endif
obj-y += mdp_dma.o
obj-y += mdp_dma_s.o
obj-y += mdp_vsync.o
obj-y += mdp_cursor.o
obj-y += mdp_dma_tv.o
# EBI2
obj-$(CONFIG_FB_MSM_EBI2) += ebi2_lcd.o
# LCDC
obj-$(CONFIG_FB_MSM_LCDC) += lcdc.o
# MDDI
msm_mddi-objs := mddi.o mddihost.o mddihosti.o
obj-$(CONFIG_FB_MSM_MDDI) += msm_mddi.o
# External MDDI
msm_mddi_ext-objs := mddihost_e.o mddi_ext.o
obj-$(CONFIG_FB_MSM_EXTMDDI) += msm_mddi_ext.o
# TVEnc
obj-$(CONFIG_FB_MSM_TVOUT) += tvenc.o
# MSM FB Panel
obj-y += msm_fb_panel.o
obj-$(CONFIG_FB_MSM_EBI2_TMD_QVGA_EPSON_QCIF) += ebi2_tmd20.o
obj-$(CONFIG_FB_MSM_EBI2_TMD_QVGA_EPSON_QCIF) += ebi2_l2f.o
ifeq ($(CONFIG_FB_MSM_MDDI_AUTO_DETECT),y)
obj-y += mddi_prism.o
obj-y += mddi_toshiba.o
obj-y += mddi_toshiba_vga.o
obj-y += mddi_toshiba_wvga_pt.o
obj-y += mddi_toshiba_wvga.o
obj-y += mddi_sharp.o
else
obj-$(CONFIG_FB_MSM_MDDI_PRISM_WVGA) += mddi_prism.o
obj-$(CONFIG_FB_MSM_MDDI_TOSHIBA_COMMON) += mddi_toshiba.o
obj-$(CONFIG_FB_MSM_MDDI_TOSHIBA_COMMON_VGA) += mddi_toshiba_vga.o
obj-$(CONFIG_FB_MSM_MDDI_TOSHIBA_WVGA_PORTRAIT) += mddi_toshiba_wvga_pt.o
obj-$(CONFIG_FB_MSM_MDDI_TOSHIBA_WVGA) += mddi_toshiba_wvga.o
obj-$(CONFIG_FB_MSM_MDDI_SHARP_QVGA_128x128) += mddi_sharp.o
endif
obj-$(CONFIG_FB_MSM_LCDC_PANEL) += lcdc_panel.o
obj-$(CONFIG_FB_MSM_LCDC_PRISM_WVGA) += lcdc_prism.o
obj-$(CONFIG_FB_MSM_LCDC_EXTERNAL_WXGA) += lcdc_external.o
obj-$(CONFIG_FB_MSM_LCDC_GORDON_VGA) += lcdc_gordon.o
obj-$(CONFIG_FB_MSM_LCDC_WXGA) += lcdc_wxga.o
obj-$(CONFIG_FB_MSM_LCDC_TOSHIBA_WVGA_PT) += lcdc_toshiba_wvga_pt.o
obj-$(CONFIG_FB_MSM_LCDC_SHARP_WVGA_PT) += lcdc_sharp_wvga_pt.o
obj-$(CONFIG_FB_MSM_LCDC_GRAPEFRUIT_VGA) += lcdc_grapefruit.o
obj-$(CONFIG_FB_MSM_LCDC_ST1_WXGA) += lcdc_st1_wxga.o
obj-$(CONFIG_FB_MSM_LCDC_ST15_WXGA) += lcdc_st15.o
obj-$(CONFIG_FB_MSM_HDMI_SII_EXTERNAL_720P) += hdmi_sii9022.o
obj-$(CONFIG_FB_MSM_TVOUT_NTSC) += tv_ntsc.o
obj-$(CONFIG_FB_MSM_TVOUT_PAL) += tv_pal.o
obj-$(CONFIG_FB_MSM_EXTMDDI_SVGA) += mddi_ext_lcd.o
clean:
rm *.o .*cmd
- Merge this code with the existing MSM framebuffer
- General style clean ups.
/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; 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., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include "msm_fb.h"
#include <linux/memory.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/time.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include "linux/proc_fs.h"
#include <linux/delay.h>
#include <mach/hardware.h>
#include <linux/io.h>
#include <asm/system.h>
#include <asm/mach-types.h>
/* The following are for MSM5100 on Gator
*/
#ifdef FEATURE_PM1000
#include "pm1000.h"
#endif /* FEATURE_PM1000 */
/* The following are for MSM6050 on Bambi
*/
#ifdef FEATURE_PMIC_LCDKBD_LED_DRIVER
#include "pm.h"
#endif /* FEATURE_PMIC_LCDKBD_LED_DRIVER */
#ifdef DISP_DEVICE_18BPP
#undef DISP_DEVICE_18BPP
#define DISP_DEVICE_16BPP
#endif
#define QCIF_WIDTH 176
#define QCIF_HEIGHT 220
static void *DISP_CMD_PORT;
static void *DISP_DATA_PORT;
#define DISP_CMD_DISON 0xaf
#define DISP_CMD_DISOFF 0xae
#define DISP_CMD_DISNOR 0xa6
#define DISP_CMD_DISINV 0xa7
#define DISP_CMD_DISCTL 0xca
#define DISP_CMD_GCP64 0xcb
#define DISP_CMD_GCP16 0xcc
#define DISP_CMD_GSSET 0xcd
#define DISP_GS_2 0x02
#define DISP_GS_16 0x01
#define DISP_GS_64 0x00
#define DISP_CMD_SLPIN 0x95
#define DISP_CMD_SLPOUT 0x94
#define DISP_CMD_SD_PSET 0x75
#define DISP_CMD_MD_PSET 0x76
#define DISP_CMD_SD_CSET 0x15
#define DISP_CMD_MD_CSET 0x16
#define DISP_CMD_DATCTL 0xbc
#define DISP_DATCTL_666 0x08
#define DISP_DATCTL_565 0x28
#define DISP_DATCTL_444 0x38
#define DISP_CMD_RAMWR 0x5c
#define DISP_CMD_RAMRD 0x5d
#define DISP_CMD_PTLIN 0xa8
#define DISP_CMD_PTLOUT 0xa9
#define DISP_CMD_ASCSET 0xaa
#define DISP_CMD_SCSTART 0xab
#define DISP_CMD_VOLCTL 0xc6
#define DISP_VOLCTL_TONE 0x80
#define DISP_CMD_NOp 0x25
#define DISP_CMD_OSSEL 0xd0
#define DISP_CMD_3500KSET 0xd1
#define DISP_CMD_3500KEND 0xd2
#define DISP_CMD_14MSET 0xd3
#define DISP_CMD_14MEND 0xd4
#define DISP_CMD_OUT(cmd) outpw(DISP_CMD_PORT, cmd);
#define DISP_DATA_OUT(data) outpw(DISP_DATA_PORT, data);
#define DISP_DATA_IN() inpw(DISP_DATA_PORT);
/* Epson device column number starts at 2
*/
#define DISP_SET_RECT(ulhc_row, lrhc_row, ulhc_col, lrhc_col) \
DISP_CMD_OUT(DISP_CMD_SD_PSET) \
DISP_DATA_OUT((ulhc_row) & 0xFF) \
DISP_DATA_OUT((ulhc_row) >> 8) \
DISP_DATA_OUT((lrhc_row) & 0xFF) \
DISP_DATA_OUT((lrhc_row) >> 8) \
DISP_CMD_OUT(DISP_CMD_SD_CSET) \
DISP_DATA_OUT(((ulhc_col)+2) & 0xFF) \
DISP_DATA_OUT(((ulhc_col)+2) >> 8) \
DISP_DATA_OUT(((lrhc_col)+2) & 0xFF) \
DISP_DATA_OUT(((lrhc_col)+2) >> 8)
#define DISP_MIN_CONTRAST 0
#define DISP_MAX_CONTRAST 127
#define DISP_DEFAULT_CONTRAST 80
#define DISP_MIN_BACKLIGHT 0
#define DISP_MAX_BACKLIGHT 15
#define DISP_DEFAULT_BACKLIGHT 2
#define WAIT_SEC(sec) mdelay((sec)/1000)
static word disp_area_start_row;
static word disp_area_end_row;
static byte disp_contrast = DISP_DEFAULT_CONTRAST;
static boolean disp_powered_up;
static boolean disp_initialized = FALSE;
/* For some reason the contrast set at init time is not good. Need to do
* it again
*/
static boolean display_on = FALSE;
static void epsonQcif_disp_init(struct platform_device *pdev);
static void epsonQcif_disp_set_contrast(word contrast);
static void epsonQcif_disp_set_display_area(word start_row, word end_row);
static int epsonQcif_disp_off(struct platform_device *pdev);
static int epsonQcif_disp_on(struct platform_device *pdev);
static void epsonQcif_disp_set_rect(int x, int y, int xres, int yres);
volatile word databack;
static void epsonQcif_disp_init(struct platform_device *pdev)
{
struct msm_fb_data_type *mfd;
int i;
if (disp_initialized)
return;
mfd = platform_get_drvdata(pdev);
DISP_CMD_PORT = mfd->cmd_port;
DISP_DATA_PORT = mfd->data_port;
/* Sleep in */
DISP_CMD_OUT(DISP_CMD_SLPIN);
/* Display off */
DISP_CMD_OUT(DISP_CMD_DISOFF);
/* Display normal */
DISP_CMD_OUT(DISP_CMD_DISNOR);
/* Set data mode */
DISP_CMD_OUT(DISP_CMD_DATCTL);
DISP_DATA_OUT(DISP_DATCTL_565);
/* Set display timing */
DISP_CMD_OUT(DISP_CMD_DISCTL);
DISP_DATA_OUT(0x1c); /* p1 */
DISP_DATA_OUT(0x02); /* p1 */
DISP_DATA_OUT(0x82); /* p2 */
DISP_DATA_OUT(0x00); /* p3 */
DISP_DATA_OUT(0x00); /* p4 */
DISP_DATA_OUT(0xe0); /* p5 */
DISP_DATA_OUT(0x00); /* p5 */
DISP_DATA_OUT(0xdc); /* p6 */
DISP_DATA_OUT(0x00); /* p6 */
DISP_DATA_OUT(0x02); /* p7 */
DISP_DATA_OUT(0x00); /* p8 */
/* Set 64 gray scale level */
DISP_CMD_OUT(DISP_CMD_GCP64);
DISP_DATA_OUT(0x08); /* p01 */
DISP_DATA_OUT(0x00);
DISP_DATA_OUT(0x2a); /* p02 */
DISP_DATA_OUT(0x00);
DISP_DATA_OUT(0x4e); /* p03 */
DISP_DATA_OUT(0x00);
DISP_DATA_OUT(0x6b); /* p04 */
DISP_DATA_OUT(0x00);
DISP_DATA_OUT(0x88); /* p05 */
DISP_DATA_OUT(0x00);
DISP_DATA_OUT(0xa3); /* p06 */
DISP_DATA_OUT(0x00);
DISP_DATA_OUT(0xba); /* p07 */
DISP_DATA_OUT(0x00);
DISP_DATA_OUT(0xd1); /* p08 */
DISP_DATA_OUT(0x00);
DISP_DATA_OUT(0xe5); /* p09 */
DISP_DATA_OUT(0x00);
DISP_DATA_OUT(0xf3); /* p10 */
DISP_DATA_OUT(0x00);
DISP_DATA_OUT(0x03); /* p11 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x13); /* p12 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x22); /* p13 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x2f); /* p14 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x3b); /* p15 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x46); /* p16 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x51); /* p17 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x5b); /* p18 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x64); /* p19 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x6c); /* p20 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x74); /* p21 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x7c); /* p22 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x83); /* p23 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x8a); /* p24 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x91); /* p25 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x98); /* p26 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x9f); /* p27 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xa6); /* p28 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xac); /* p29 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xb2); /* p30 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xb7); /* p31 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xbc); /* p32 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xc1); /* p33 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xc6); /* p34 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xcb); /* p35 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xd0); /* p36 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xd4); /* p37 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xd8); /* p38 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xdc); /* p39 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xe0); /* p40 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xe4); /* p41 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xe8); /* p42 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xec); /* p43 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xf0); /* p44 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xf4); /* p45 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xf8); /* p46 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xfb); /* p47 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xfe); /* p48 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x01); /* p49 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x03); /* p50 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x05); /* p51 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x07); /* p52 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x09); /* p53 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x0b); /* p54 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x0d); /* p55 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x0f); /* p56 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x11); /* p57 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x13); /* p58 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x15); /* p59 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x17); /* p60 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x19); /* p61 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x1b); /* p62 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x1c); /* p63 */
DISP_DATA_OUT(0x02);
/* Set 16 gray scale level */
DISP_CMD_OUT(DISP_CMD_GCP16);
DISP_DATA_OUT(0x1a); /* p01 */
DISP_DATA_OUT(0x32); /* p02 */
DISP_DATA_OUT(0x42); /* p03 */
DISP_DATA_OUT(0x4c); /* p04 */
DISP_DATA_OUT(0x58); /* p05 */
DISP_DATA_OUT(0x5f); /* p06 */
DISP_DATA_OUT(0x66); /* p07 */
DISP_DATA_OUT(0x6b); /* p08 */
DISP_DATA_OUT(0x70); /* p09 */
DISP_DATA_OUT(0x74); /* p10 */
DISP_DATA_OUT(0x78); /* p11 */
DISP_DATA_OUT(0x7b); /* p12 */
DISP_DATA_OUT(0x7e); /* p13 */
DISP_DATA_OUT(0x80); /* p14 */
DISP_DATA_OUT(0x82); /* p15 */
/* Set DSP column */
DISP_CMD_OUT(DISP_CMD_MD_CSET);
DISP_DATA_OUT(0xff);
DISP_DATA_OUT(0x03);
DISP_DATA_OUT(0xff);
DISP_DATA_OUT(0x03);
/* Set DSP page */
DISP_CMD_OUT(DISP_CMD_MD_PSET);
DISP_DATA_OUT(0xff);
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xff);
DISP_DATA_OUT(0x01);
/* Set ARM column */
DISP_CMD_OUT(DISP_CMD_SD_CSET);
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x00);
DISP_DATA_OUT((QCIF_WIDTH + 1) & 0xFF);
DISP_DATA_OUT((QCIF_WIDTH + 1) >> 8);
/* Set ARM page */
DISP_CMD_OUT(DISP_CMD_SD_PSET);
DISP_DATA_OUT(0x00);
DISP_DATA_OUT(0x00);
DISP_DATA_OUT((QCIF_HEIGHT - 1) & 0xFF);
DISP_DATA_OUT((QCIF_HEIGHT - 1) >> 8);
/* Set 64 gray scales */
DISP_CMD_OUT(DISP_CMD_GSSET);
DISP_DATA_OUT(DISP_GS_64);
DISP_CMD_OUT(DISP_CMD_OSSEL);
DISP_DATA_OUT(0);
/* Sleep out */
DISP_CMD_OUT(DISP_CMD_SLPOUT);
WAIT_SEC(40000);
/* Initialize power IC */
DISP_CMD_OUT(DISP_CMD_VOLCTL);
DISP_DATA_OUT(DISP_VOLCTL_TONE);
WAIT_SEC(40000);
/* Set electronic volume, d'xx */
DISP_CMD_OUT(DISP_CMD_VOLCTL);
DISP_DATA_OUT(DISP_DEFAULT_CONTRAST); /* value from 0 to 127 */
/* Initialize display data */
DISP_SET_RECT(0, (QCIF_HEIGHT - 1), 0, (QCIF_WIDTH - 1));
DISP_CMD_OUT(DISP_CMD_RAMWR);
for (i = 0; i < QCIF_HEIGHT * QCIF_WIDTH; i++)
DISP_DATA_OUT(0xffff);
DISP_CMD_OUT(DISP_CMD_RAMRD);
databack = DISP_DATA_IN();
databack = DISP_DATA_IN();
databack = DISP_DATA_IN();
databack = DISP_DATA_IN();
WAIT_SEC(80000);
DISP_CMD_OUT(DISP_CMD_DISON);
disp_area_start_row = 0;
disp_area_end_row = QCIF_HEIGHT - 1;
disp_powered_up = TRUE;
disp_initialized = TRUE;
epsonQcif_disp_set_display_area(0, QCIF_HEIGHT - 1);
display_on = TRUE;
}
static void epsonQcif_disp_set_rect(int x, int y, int xres, int yres)
{
if (!disp_initialized)
return;
DISP_SET_RECT(y, y + yres - 1, x, x + xres - 1);
DISP_CMD_OUT(DISP_CMD_RAMWR);
}
static void epsonQcif_disp_set_display_area(word start_row, word end_row)
{
if (!disp_initialized)
return;
if ((start_row == disp_area_start_row)
&& (end_row == disp_area_end_row))
return;
disp_area_start_row = start_row;
disp_area_end_row = end_row;
/* Range checking
*/
if (end_row >= QCIF_HEIGHT)
end_row = QCIF_HEIGHT - 1;
if (start_row > end_row)
start_row = end_row;
/* When display is not the full screen, gray scale is set to
** 2; otherwise it is set to 64.
*/
if ((start_row == 0) && (end_row == (QCIF_HEIGHT - 1))) {
/* The whole screen */
DISP_CMD_OUT(DISP_CMD_PTLOUT);
WAIT_SEC(10000);
DISP_CMD_OUT(DISP_CMD_DISOFF);
WAIT_SEC(100000);
DISP_CMD_OUT(DISP_CMD_GSSET);
DISP_DATA_OUT(DISP_GS_64);
WAIT_SEC(100000);
DISP_CMD_OUT(DISP_CMD_DISON);
} else {
/* partial screen */
DISP_CMD_OUT(DISP_CMD_PTLIN);
DISP_DATA_OUT(start_row);
DISP_DATA_OUT(start_row >> 8);
DISP_DATA_OUT(end_row);
DISP_DATA_OUT(end_row >> 8);
DISP_CMD_OUT(DISP_CMD_GSSET);
DISP_DATA_OUT(DISP_GS_2);
}
}
static int epsonQcif_disp_off(struct platform_device *pdev)
{
if (!disp_initialized)
epsonQcif_disp_init(pdev);
if (display_on) {
DISP_CMD_OUT(DISP_CMD_DISOFF);
DISP_CMD_OUT(DISP_CMD_SLPIN);
display_on = FALSE;
}
return 0;
}
static int epsonQcif_disp_on(struct platform_device *pdev)
{
if (!disp_initialized)
epsonQcif_disp_init(pdev);
if (!display_on) {
DISP_CMD_OUT(DISP_CMD_SLPOUT);
WAIT_SEC(40000);
DISP_CMD_OUT(DISP_CMD_DISON);
epsonQcif_disp_set_contrast(disp_contrast);
display_on = TRUE;
}
return 0;
}
static void epsonQcif_disp_set_contrast(word contrast)
{
if (!disp_initialized)
return;
/* Initialize power IC, d'24 */
DISP_CMD_OUT(DISP_CMD_VOLCTL);
DISP_DATA_OUT(DISP_VOLCTL_TONE);
WAIT_SEC(40000);
/* Set electronic volume, d'xx */
DISP_CMD_OUT(DISP_CMD_VOLCTL);
if (contrast > 127)
contrast = 127;
DISP_DATA_OUT(contrast); /* value from 0 to 127 */
disp_contrast = (byte) contrast;
} /* End disp_set_contrast */
static void epsonQcif_disp_clear_screen_area(
word start_row, word end_row, word start_column, word end_column) {
int32 i;
/* Clear the display screen */
DISP_SET_RECT(start_row, end_row, start_column, end_column);
DISP_CMD_OUT(DISP_CMD_RAMWR);
i = (end_row - start_row + 1) * (end_column - start_column + 1);
for (; i > 0; i--)
DISP_DATA_OUT(0xffff);
}
static int __init epsonQcif_probe(struct platform_device *pdev)
{
msm_fb_add_device(pdev);
return 0;
}
static struct platform_driver this_driver = {
.probe = epsonQcif_probe,
.driver = {
.name = "ebi2_epson_qcif",
},
};
static struct msm_fb_panel_data epsonQcif_panel_data = {
.on = epsonQcif_disp_on,
.off = epsonQcif_disp_off,
.set_rect = epsonQcif_disp_set_rect,
};
static struct platform_device this_device = {
.name = "ebi2_epson_qcif",
.id = 0,
.dev = {
.platform_data = &epsonQcif_panel_data,
}
};
static int __init epsonQcif_init(void)
{
int ret;
struct msm_panel_info *pinfo;
ret = platform_driver_register(&this_driver);
if (!ret) {
pinfo = &epsonQcif_panel_data.panel_info;
pinfo->xres = QCIF_WIDTH;
pinfo->yres = QCIF_HEIGHT;
pinfo->type = EBI2_PANEL;
pinfo->pdest = DISPLAY_2;
pinfo->wait_cycle = 0x808000;
pinfo->bpp = 16;
pinfo->fb_num = 2;
pinfo->lcd.vsync_enable = FALSE;
ret = platform_device_register(&this_device);
if (ret)
platform_driver_unregister(&this_driver);
}
return ret;
}
module_init(epsonQcif_init);
/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; 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., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/mm.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/uaccess.h>
#include <linux/workqueue.h>
#include <linux/string.h>
#include <linux/version.h>
#include <linux/proc_fs.h>
#include <linux/vmalloc.h>
#include <linux/debugfs.h>
#include "msm_fb.h"
static int ebi2_lcd_probe(struct platform_device *pdev);
static int ebi2_lcd_remove(struct platform_device *pdev);
static struct platform_driver ebi2_lcd_driver = {
.probe = ebi2_lcd_probe,
.remove = ebi2_lcd_remove,
.suspend = NULL,
.suspend_late = NULL,
.resume_early = NULL,
.resume = NULL,
.shutdown = NULL,
.driver = {
.name = "ebi2_lcd",
},
};
static void *ebi2_base;
static void *ebi2_lcd_cfg0;
static void *ebi2_lcd_cfg1;
static void __iomem *lcd01_base;
static void __iomem *lcd02_base;
static int ebi2_lcd_resource_initialized;
static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
static int pdev_list_cnt;
static int ebi2_lcd_probe(struct platform_device *pdev)
{
struct msm_fb_data_type *mfd;
struct platform_device *mdp_dev = NULL;
struct msm_fb_panel_data *pdata = NULL;
int rc, i;
if (pdev->id == 0) {
for (i = 0; i < pdev->num_resources; i++) {
if (!strncmp(pdev->resource[i].name, "base", 4)) {
ebi2_base = ioremap(pdev->resource[i].start,
pdev->resource[i].end -
pdev->resource[i].start + 1);
if (!ebi2_base) {
printk(KERN_ERR
"ebi2_base ioremap failed!\n");
return -ENOMEM;
}
ebi2_lcd_cfg0 = (void *)(ebi2_base + 0x20);
ebi2_lcd_cfg1 = (void *)(ebi2_base + 0x24);
} else if (!strncmp(pdev->resource[i].name,
"lcd01", 5)) {
lcd01_base = ioremap(pdev->resource[i].start,
pdev->resource[i].end -
pdev->resource[i].start + 1);
if (!lcd01_base) {
printk(KERN_ERR
"lcd01_base ioremap failed!\n");
return -ENOMEM;
}
} else if (!strncmp(pdev->resource[i].name,
"lcd02", 5)) {
lcd02_base = ioremap(pdev->resource[i].start,
pdev->resource[i].end -
pdev->resource[i].start + 1);
if (!lcd02_base) {
printk(KERN_ERR
"lcd02_base ioremap failed!\n");
return -ENOMEM;
}
}
}
ebi2_lcd_resource_initialized = 1;
return 0;
}
if (!ebi2_lcd_resource_initialized)
return -EPERM;
mfd = platform_get_drvdata(pdev);
if (!mfd)
return -ENODEV;
if (mfd->key != MFD_KEY)
return -EINVAL;
if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
return -ENOMEM;
if (ebi2_base == NULL)
return -ENOMEM;
mdp_dev = platform_device_alloc("mdp", pdev->id);
if (!mdp_dev)
return -ENOMEM;
/* link to the latest pdev */
mfd->pdev = mdp_dev;
mfd->dest = DISPLAY_LCD;
/* add panel data */
if (platform_device_add_data
(mdp_dev, pdev->dev.platform_data,
sizeof(struct msm_fb_panel_data))) {
printk(KERN_ERR "ebi2_lcd_probe: platform_device_add_data failed!\n");
platform_device_put(mdp_dev);
return -ENOMEM;
}
/* data chain */
pdata = mdp_dev->dev.platform_data;
pdata->on = panel_next_on;
pdata->off = panel_next_off;
pdata->next = pdev;
/* get/set panel specific fb info */
mfd->panel_info = pdata->panel_info;
if (mfd->panel_info.bpp == 24)
mfd->fb_imgType = MDP_RGB_888;
else
mfd->fb_imgType = MDP_RGB_565;
/* config msm ebi2 lcd register */
if (mfd->panel_info.pdest == DISPLAY_1) {
outp32(ebi2_base,
(inp32(ebi2_base) & (~(EBI2_PRIM_LCD_CLR))) |
EBI2_PRIM_LCD_SEL);
/*
* current design has one set of cfg0/1 register to control
* both EBI2 channels. so, we're using the PRIM channel to
* configure both.
*/
outp32(ebi2_lcd_cfg0, mfd->panel_info.wait_cycle);
if (mfd->panel_info.bpp == 18)
outp32(ebi2_lcd_cfg1, 0x01000000);
else
outp32(ebi2_lcd_cfg1, 0x0);
} else {
#ifdef DEBUG_EBI2_LCD
/*
* confliting with QCOM SURF FPGA CS.
* OEM should enable below for their CS mapping
*/
outp32(ebi2_base, (inp32(ebi2_base)&(~(EBI2_SECD_LCD_CLR)))
|EBI2_SECD_LCD_SEL);
#endif
}
/*
* map cs (chip select) address
*/
if (mfd->panel_info.pdest == DISPLAY_1) {
mfd->cmd_port = lcd01_base;
mfd->data_port =
(void *)((uint32) mfd->cmd_port + EBI2_PRIM_LCD_RS_PIN);
mfd->data_port_phys =
(void *)(LCD_PRIM_BASE_PHYS + EBI2_PRIM_LCD_RS_PIN);
} else {
mfd->cmd_port = lcd01_base;
mfd->data_port =
(void *)((uint32) mfd->cmd_port + EBI2_SECD_LCD_RS_PIN);
mfd->data_port_phys =
(void *)(LCD_SECD_BASE_PHYS + EBI2_SECD_LCD_RS_PIN);
}
/*
* set driver data
*/
platform_set_drvdata(mdp_dev, mfd);
/*
* register in mdp driver
*/
rc = platform_device_add(mdp_dev);
if (rc) {
goto ebi2_lcd_probe_err;
}
pdev_list[pdev_list_cnt++] = pdev;
return 0;
ebi2_lcd_probe_err:
platform_device_put(mdp_dev);
return rc;
}
static int ebi2_lcd_remove(struct platform_device *pdev)
{
struct msm_fb_data_type *mfd;
mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
if (!mfd)
return 0;
if (mfd->key != MFD_KEY)
return 0;
iounmap(mfd->cmd_port);
return 0;
}
static int ebi2_lcd_register_driver(void)
{
return platform_driver_register(&ebi2_lcd_driver);
}
static int __init ebi2_lcd_driver_init(void)
{
return ebi2_lcd_register_driver();
}
module_init(ebi2_lcd_driver_init);
\ No newline at end of file
此差异已折叠。
/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; 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., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include <linux/i2c.h>
#include <linux/delay.h>
#include "msm_fb.h"
#define DEVICE_NAME "sii9022"
#define SII9022_DEVICE_ID 0xB0
struct sii9022_i2c_addr_data{
u8 addr;
u8 data;
};
/* video mode data */
static u8 video_mode_data[] = {
0x00,
0xF9, 0x1C, 0x70, 0x17, 0x72, 0x06, 0xEE, 0x02,
};
static u8 avi_io_format[] = {
0x09,
0x00, 0x00,
};
/* power state */
static struct sii9022_i2c_addr_data regset0[] = {
{ 0x60, 0x04 },
{ 0x63, 0x00 },
{ 0x1E, 0x00 },
};
static u8 video_infoframe[] = {
0x0C,
0xF0, 0x00, 0x68, 0x00, 0x04, 0x00, 0x19, 0x00,
0xE9, 0x02, 0x04, 0x01, 0x04, 0x06,
};
/* configure audio */
static struct sii9022_i2c_addr_data regset1[] = {
{ 0x26, 0x90 },
{ 0x20, 0x90 },
{ 0x1F, 0x80 },
{ 0x26, 0x80 },
{ 0x24, 0x02 },
{ 0x25, 0x0B },
{ 0xBC, 0x02 },
{ 0xBD, 0x24 },
{ 0xBE, 0x02 },
};
/* enable audio */
static u8 misc_infoframe[] = {
0xBF,
0xC2, 0x84, 0x01, 0x0A, 0x6F, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
/* set HDMI, active */
static struct sii9022_i2c_addr_data regset2[] = {
{ 0x1A, 0x01 },
{ 0x3D, 0x00 },
};
static int send_i2c_data(struct i2c_client *client,
struct sii9022_i2c_addr_data *regset,
int size)
{
int i;
int rc = 0;
for (i = 0; i < size; i++) {
rc = i2c_smbus_write_byte_data(
client,
regset[i].addr, regset[i].data);
if (rc)
break;
}
return rc;
}
static int hdmi_sii_enable(struct i2c_client *client)
{
int rc;
int retries = 10;
int count;
rc = i2c_smbus_write_byte_data(client, 0xC7, 0x00);
if (rc)
goto enable_exit;
do {
msleep(1);
rc = i2c_smbus_read_byte_data(client, 0x1B);
} while ((rc != SII9022_DEVICE_ID) && retries--);
if (rc != SII9022_DEVICE_ID)
return -ENODEV;
rc = i2c_smbus_write_byte_data(client, 0x1A, 0x11);
if (rc)
goto enable_exit;
count = ARRAY_SIZE(video_mode_data);
rc = i2c_master_send(client, video_mode_data, count);
if (rc != count) {
rc = -EIO;
goto enable_exit;
}
rc = i2c_smbus_write_byte_data(client, 0x08, 0x20);
if (rc)
goto enable_exit;
count = ARRAY_SIZE(avi_io_format);
rc = i2c_master_send(client, avi_io_format, count);
if (rc != count) {
rc = -EIO;
goto enable_exit;
}
rc = send_i2c_data(client, regset0, ARRAY_SIZE(regset0));
if (rc)
goto enable_exit;
count = ARRAY_SIZE(video_infoframe);
rc = i2c_master_send(client, video_infoframe, count);
if (rc != count) {
rc = -EIO;
goto enable_exit;
}
rc = send_i2c_data(client, regset1, ARRAY_SIZE(regset1));
if (rc)
goto enable_exit;
count = ARRAY_SIZE(misc_infoframe);
rc = i2c_master_send(client, misc_infoframe, count);
if (rc != count) {
rc = -EIO;
goto enable_exit;
}
rc = send_i2c_data(client, regset2, ARRAY_SIZE(regset2));
if (rc)
goto enable_exit;
return 0;
enable_exit:
printk(KERN_ERR "%s: exited rc=%d\n", __func__, rc);
return rc;
}
static const struct i2c_device_id hmdi_sii_id[] = {
{ DEVICE_NAME, 0 },
{ }
};
static int hdmi_sii_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int rc;
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_BYTE | I2C_FUNC_I2C))
return -ENODEV;
rc = hdmi_sii_enable(client);
return rc;
}
static struct i2c_driver hdmi_sii_i2c_driver = {
.driver = {
.name = DEVICE_NAME,
.owner = THIS_MODULE,
},
.probe = hdmi_sii_probe,
.remove = __exit_p(hdmi_sii_remove),
.id_table = hmdi_sii_id,
};
static int __init hdmi_sii_init(void)
{
int ret;
struct msm_panel_info pinfo;
if (msm_fb_detect_client("hdmi_sii9022"))
return 0;
pinfo.xres = 1280;
pinfo.yres = 720;
pinfo.type = HDMI_PANEL;
pinfo.pdest = DISPLAY_1;
pinfo.wait_cycle = 0;
pinfo.bpp = 24;
pinfo.fb_num = 2;
pinfo.clk_rate = 74250000;
pinfo.lcdc.h_back_porch = 124;
pinfo.lcdc.h_front_porch = 110;
pinfo.lcdc.h_pulse_width = 136;
pinfo.lcdc.v_back_porch = 19;
pinfo.lcdc.v_front_porch = 5;
pinfo.lcdc.v_pulse_width = 6;
pinfo.lcdc.border_clr = 0;
pinfo.lcdc.underflow_clr = 0xff;
pinfo.lcdc.hsync_skew = 0;
ret = lcdc_device_register(&pinfo);
if (ret) {
printk(KERN_ERR "%s: failed to register device\n", __func__);
goto init_exit;
}
ret = i2c_add_driver(&hdmi_sii_i2c_driver);
if (ret)
printk(KERN_ERR "%s: failed to add i2c driver\n", __func__);
init_exit:
return ret;
}
static void __exit hdmi_sii_exit(void)
{
i2c_del_driver(&hdmi_sii_i2c_driver);
}
module_init(hdmi_sii_init);
module_exit(hdmi_sii_exit);
MODULE_LICENSE("GPL v2");
MODULE_VERSION("0.1");
MODULE_AUTHOR("Qualcomm Innovation Center, Inc.");
MODULE_DESCRIPTION("SiI9022 HDMI driver");
MODULE_ALIAS("platform:hdmi-sii9022");
/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; 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., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/time.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
#include <mach/hardware.h>
#include <linux/io.h>
#include <asm/system.h>
#include <asm/mach-types.h>
#include <linux/semaphore.h>
#include <linux/uaccess.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/pm_qos_params.h>
#include "msm_fb.h"
static int lcdc_probe(struct platform_device *pdev);
static int lcdc_remove(struct platform_device *pdev);
static int lcdc_off(struct platform_device *pdev);
static int lcdc_on(struct platform_device *pdev);
static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
static int pdev_list_cnt;
static struct clk *mdp_lcdc_pclk_clk;
static struct clk *mdp_lcdc_pad_pclk_clk;
int mdp_lcdc_pclk_clk_rate;
int mdp_lcdc_pad_pclk_clk_rate;
static struct platform_driver lcdc_driver = {
.probe = lcdc_probe,
.remove = lcdc_remove,
.suspend = NULL,
.resume = NULL,
.shutdown = NULL,
.driver = {
.name = "lcdc",
},
};
static struct lcdc_platform_data *lcdc_pdata;
static int lcdc_off(struct platform_device *pdev)
{
int ret = 0;
ret = panel_next_off(pdev);
clk_disable(mdp_lcdc_pclk_clk);
clk_disable(mdp_lcdc_pad_pclk_clk);
if (lcdc_pdata && lcdc_pdata->lcdc_power_save)
lcdc_pdata->lcdc_power_save(0);
if (lcdc_pdata && lcdc_pdata->lcdc_gpio_config)
ret = lcdc_pdata->lcdc_gpio_config(0);
// pm_qos_update_requirement(PM_QOS_SYSTEM_BUS_FREQ , "lcdc",
// PM_QOS_DEFAULT_VALUE);
return ret;
}
static int lcdc_on(struct platform_device *pdev)
{
int ret = 0;
struct msm_fb_data_type *mfd;
unsigned long panel_pixclock_freq , pm_qos_freq;
mfd = platform_get_drvdata(pdev);
panel_pixclock_freq = mfd->fbi->var.pixclock;
if (panel_pixclock_freq > 58000000)
/* pm_qos_freq should be in Khz */
pm_qos_freq = panel_pixclock_freq / 1000 ;
else
pm_qos_freq = 58000;
// pm_qos_update_requirement(PM_QOS_SYSTEM_BUS_FREQ , "lcdc",
// pm_qos_freq);
mfd = platform_get_drvdata(pdev);
clk_enable(mdp_lcdc_pclk_clk);
clk_enable(mdp_lcdc_pad_pclk_clk);
if (lcdc_pdata && lcdc_pdata->lcdc_power_save)
lcdc_pdata->lcdc_power_save(1);
if (lcdc_pdata && lcdc_pdata->lcdc_gpio_config)
ret = lcdc_pdata->lcdc_gpio_config(1);
clk_set_rate(mdp_lcdc_pclk_clk, mfd->fbi->var.pixclock);
clk_set_rate(mdp_lcdc_pad_pclk_clk, mfd->fbi->var.pixclock);
mdp_lcdc_pclk_clk_rate = clk_get_rate(mdp_lcdc_pclk_clk);
mdp_lcdc_pad_pclk_clk_rate = clk_get_rate(mdp_lcdc_pad_pclk_clk);
ret = panel_next_on(pdev);
return ret;
}
static int lcdc_probe(struct platform_device *pdev)
{
struct msm_fb_data_type *mfd;
struct fb_info *fbi;
struct platform_device *mdp_dev = NULL;
struct msm_fb_panel_data *pdata = NULL;
int rc;
if (pdev->id == 0) {
lcdc_pdata = pdev->dev.platform_data;
return 0;
}
mfd = platform_get_drvdata(pdev);
if (!mfd)
return -ENODEV;
if (mfd->key != MFD_KEY)
return -EINVAL;
if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
return -ENOMEM;
mdp_dev = platform_device_alloc("mdp", pdev->id);
if (!mdp_dev)
return -ENOMEM;
/*
* link to the latest pdev
*/
mfd->pdev = mdp_dev;
mfd->dest = DISPLAY_LCDC;
/*
* alloc panel device data
*/
if (platform_device_add_data
(mdp_dev, pdev->dev.platform_data,
sizeof(struct msm_fb_panel_data))) {
printk(KERN_ERR "lcdc_probe: platform_device_add_data failed!\n");
platform_device_put(mdp_dev);
return -ENOMEM;
}
/*
* data chain
*/
pdata = (struct msm_fb_panel_data *)mdp_dev->dev.platform_data;
pdata->on = lcdc_on;
pdata->off = lcdc_off;
pdata->next = pdev;
/*
* get/set panel specific fb info
*/
mfd->panel_info = pdata->panel_info;
mfd->fb_imgType = MDP_RGB_565;
fbi = mfd->fbi;
fbi->var.pixclock = mfd->panel_info.clk_rate;
fbi->var.left_margin = mfd->panel_info.lcdc.h_back_porch;
fbi->var.right_margin = mfd->panel_info.lcdc.h_front_porch;
fbi->var.upper_margin = mfd->panel_info.lcdc.v_back_porch;
fbi->var.lower_margin = mfd->panel_info.lcdc.v_front_porch;
fbi->var.hsync_len = mfd->panel_info.lcdc.h_pulse_width;
fbi->var.vsync_len = mfd->panel_info.lcdc.v_pulse_width;
/*
* set driver data
*/
platform_set_drvdata(mdp_dev, mfd);
/*
* register in mdp driver
*/
rc = platform_device_add(mdp_dev);
if (rc)
goto lcdc_probe_err;
pdev_list[pdev_list_cnt++] = pdev;
return 0;
lcdc_probe_err:
platform_device_put(mdp_dev);
return rc;
}
static int lcdc_remove(struct platform_device *pdev)
{
// pm_qos_remove_requirement(PM_QOS_SYSTEM_BUS_FREQ , "lcdc");
return 0;
}
static int lcdc_register_driver(void)
{
return platform_driver_register(&lcdc_driver);
}
static int __init lcdc_driver_init(void)
{
mdp_lcdc_pclk_clk = clk_get(NULL, "mdp_lcdc_pclk_clk");
if (IS_ERR(mdp_lcdc_pclk_clk)) {
printk(KERN_ERR "error: can't get mdp_lcdc_pclk_clk!\n");
return IS_ERR(mdp_lcdc_pclk_clk);
}
mdp_lcdc_pad_pclk_clk = clk_get(NULL, "mdp_lcdc_pad_pclk_clk");
if (IS_ERR(mdp_lcdc_pad_pclk_clk)) {
printk(KERN_ERR "error: can't get mdp_lcdc_pad_pclk_clk!\n");
return IS_ERR(mdp_lcdc_pad_pclk_clk);
}
// pm_qos_add_requirement(PM_QOS_SYSTEM_BUS_FREQ , "lcdc",
// PM_QOS_DEFAULT_VALUE);
return lcdc_register_driver();
}
module_init(lcdc_driver_init);
/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; 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., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include "msm_fb.h"
static int __init lcdc_external_init(void)
{
int ret;
struct msm_panel_info pinfo;
if (msm_fb_detect_client("lcdc_external"))
return 0;
pinfo.xres = 1280;
pinfo.yres = 720;
pinfo.type = LCDC_PANEL;
pinfo.pdest = DISPLAY_1;
pinfo.wait_cycle = 0;
pinfo.bpp = 24;
pinfo.fb_num = 2;
pinfo.clk_rate = 74250000;
pinfo.lcdc.h_back_porch = 124;
pinfo.lcdc.h_front_porch = 110;
pinfo.lcdc.h_pulse_width = 136;
pinfo.lcdc.v_back_porch = 19;
pinfo.lcdc.v_front_porch = 5;
pinfo.lcdc.v_pulse_width = 6;
pinfo.lcdc.border_clr = 0; /* blk */
pinfo.lcdc.underflow_clr = 0xff; /* blue */
pinfo.lcdc.hsync_skew = 0;
ret = lcdc_device_register(&pinfo);
if (ret)
printk(KERN_ERR "%s: failed to register device!\n", __func__);
return ret;
}
module_init(lcdc_external_init);
此差异已折叠。
/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; 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., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include "msm_fb.h"
#ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM
#include "mddihosti.h"
#endif
static int __init lcdc_grapefruit_init(void)
{
int ret;
struct msm_panel_info pinfo;
#ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM
if (msm_fb_detect_client("lcdc_grapefruit_vga"))
return 0;
#endif
pinfo.xres = 1024;
pinfo.yres = 600;
pinfo.type = LCDC_PANEL;
pinfo.pdest = DISPLAY_1;
pinfo.wait_cycle = 0;
pinfo.bpp = 18;
pinfo.fb_num = 2;
pinfo.clk_rate = 40000000;
pinfo.lcdc.h_back_porch = 88;
pinfo.lcdc.h_front_porch = 40;
pinfo.lcdc.h_pulse_width = 128;
pinfo.lcdc.v_back_porch = 23;
pinfo.lcdc.v_front_porch = 1;
pinfo.lcdc.v_pulse_width = 4;
pinfo.lcdc.border_clr = 0; /* blk */
pinfo.lcdc.underflow_clr = 0xff; /* blue */
pinfo.lcdc.hsync_skew = 0;
ret = lcdc_device_register(&pinfo);
if (ret)
printk(KERN_ERR "%s: failed to register device!\n", __func__);
return ret;
}
module_init(lcdc_grapefruit_init);
/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; 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., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include "msm_fb.h"
static int lcdc_panel_on(struct platform_device *pdev)
{
return 0;
}
static int lcdc_panel_off(struct platform_device *pdev)
{
return 0;
}
static int __init lcdc_panel_probe(struct platform_device *pdev)
{
msm_fb_add_device(pdev);
return 0;
}
static struct platform_driver this_driver = {
.probe = lcdc_panel_probe,
.driver = {
.name = "lcdc_panel",
},
};
static struct msm_fb_panel_data lcdc_panel_data = {
.on = lcdc_panel_on,
.off = lcdc_panel_off,
};
static int lcdc_dev_id;
int lcdc_device_register(struct msm_panel_info *pinfo)
{
struct platform_device *pdev = NULL;
int ret;
pdev = platform_device_alloc("lcdc_panel", ++lcdc_dev_id);
if (!pdev)
return -ENOMEM;
lcdc_panel_data.panel_info = *pinfo;
ret = platform_device_add_data(pdev, &lcdc_panel_data,
sizeof(lcdc_panel_data));
if (ret) {
printk(KERN_ERR
"%s: platform_device_add_data failed!\n", __func__);
goto err_device_put;
}
ret = platform_device_add(pdev);
if (ret) {
printk(KERN_ERR
"%s: platform_device_register failed!\n", __func__);
goto err_device_put;
}
return 0;
err_device_put:
platform_device_put(pdev);
return ret;
}
static int __init lcdc_panel_init(void)
{
return platform_driver_register(&this_driver);
}
module_init(lcdc_panel_init);
/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; 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., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include "msm_fb.h"
#ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM
#include "mddihosti.h"
#endif
static int __init lcdc_prism_init(void)
{
int ret;
struct msm_panel_info pinfo;
#ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM
ret = msm_fb_detect_client("lcdc_prism_wvga");
if (ret == -ENODEV)
return 0;
if (ret && (mddi_get_client_id() != 0))
return 0;
#endif
pinfo.xres = 800;
pinfo.yres = 480;
pinfo.type = LCDC_PANEL;
pinfo.pdest = DISPLAY_1;
pinfo.wait_cycle = 0;
pinfo.bpp = 24;
pinfo.fb_num = 2;
pinfo.clk_rate = 38460000;
pinfo.lcdc.h_back_porch = 21;
pinfo.lcdc.h_front_porch = 81;
pinfo.lcdc.h_pulse_width = 60;
pinfo.lcdc.v_back_porch = 18;
pinfo.lcdc.v_front_porch = 27;
pinfo.lcdc.v_pulse_width = 2;
pinfo.lcdc.border_clr = 0; /* blk */
pinfo.lcdc.underflow_clr = 0xff; /* blue */
pinfo.lcdc.hsync_skew = 0;
ret = lcdc_device_register(&pinfo);
if (ret)
printk(KERN_ERR "%s: failed to register device!\n", __func__);
return ret;
}
module_init(lcdc_prism_init);
此差异已折叠。
此差异已折叠。
/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; 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., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include "msm_fb.h"
static int __init lcdc_st1_wxga_init(void)
{
int ret;
struct msm_panel_info pinfo;
if (msm_fb_detect_client("lcdc_st1_wxga"))
return 0;
pinfo.xres = 1280;
pinfo.yres = 720;
pinfo.type = LCDC_PANEL;
pinfo.pdest = DISPLAY_1;
pinfo.wait_cycle = 0;
pinfo.bpp = 18;
pinfo.fb_num = 2;
pinfo.clk_rate = 74250000;
pinfo.lcdc.h_back_porch = 124;
pinfo.lcdc.h_front_porch = 110;
pinfo.lcdc.h_pulse_width = 136;
pinfo.lcdc.v_back_porch = 19;
pinfo.lcdc.v_front_porch = 5;
pinfo.lcdc.v_pulse_width = 6;
pinfo.lcdc.border_clr = 0; /* blk */
pinfo.lcdc.underflow_clr = 0xff; /* blue */
pinfo.lcdc.hsync_skew = 0;
ret = lcdc_device_register(&pinfo);
if (ret)
printk(KERN_ERR "%s: failed to register device!\n", __func__);
return ret;
}
module_init(lcdc_st1_wxga_init);
此差异已折叠。
/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; 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., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include "msm_fb.h"
static int __init lcdc_wxga_init(void)
{
int ret;
struct msm_panel_info pinfo;
#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
if (msm_fb_detect_client("lcdc_wxga"))
return 0;
#endif
pinfo.xres = 1280;
pinfo.yres = 720;
pinfo.type = LCDC_PANEL;
pinfo.pdest = DISPLAY_1;
pinfo.wait_cycle = 0;
pinfo.bpp = 24;
pinfo.fb_num = 2;
pinfo.clk_rate = 74250000;
pinfo.lcdc.h_back_porch = 124;
pinfo.lcdc.h_front_porch = 110;
pinfo.lcdc.h_pulse_width = 136;
pinfo.lcdc.v_back_porch = 19;
pinfo.lcdc.v_front_porch = 5;
pinfo.lcdc.v_pulse_width = 6;
pinfo.lcdc.border_clr = 0; /* blk */
pinfo.lcdc.underflow_clr = 0xff; /* blue */
pinfo.lcdc.hsync_skew = 0;
ret = lcdc_device_register(&pinfo);
if (ret)
printk(KERN_ERR "%s: failed to register device!\n", __func__);
return ret;
}
module_init(lcdc_wxga_init);
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册