diff options
Diffstat (limited to 'drivers/gpu/drm/emgd/emgd/display/pi/plb/i2c_plb.c')
-rw-r--r-- | drivers/gpu/drm/emgd/emgd/display/pi/plb/i2c_plb.c | 941 |
1 files changed, 0 insertions, 941 deletions
diff --git a/drivers/gpu/drm/emgd/emgd/display/pi/plb/i2c_plb.c b/drivers/gpu/drm/emgd/emgd/display/pi/plb/i2c_plb.c deleted file mode 100644 index 9fdc82d21b9e..000000000000 --- a/drivers/gpu/drm/emgd/emgd/display/pi/plb/i2c_plb.c +++ /dev/null @@ -1,941 +0,0 @@ -/* -*- pse-c -*- - *----------------------------------------------------------------------------- - * Filename: i2c_plb.c - * $Revision: 1.9 $ - *----------------------------------------------------------------------------- - * Copyright © 2002-2010, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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 St - Fifth Floor, Boston, MA 02110-1301 USA. - * - *----------------------------------------------------------------------------- - * Description: - * - *----------------------------------------------------------------------------- - */ - -#define MODULE_NAME hal.dpd - -#include <io.h> -#include <memory.h> -#include <sched.h> - -#include <igd_pwr.h> - -#include <general.h> -#include <context.h> -#include <mode.h> -#include <utils.h> - -#include <plb/regs.h> - -#include "../cmn/i2c_dispatch.h" - -/*! - * @addtogroup display_group - * @{ - */ - -/*......................................................................... */ -extern igd_display_port_t dvob_port_plb; - -/*......................................................................... */ -static int i2c_read_regs_plb( - igd_context_t *context, - unsigned long i2c_bus, - unsigned long i2c_speed, - unsigned long dab, - unsigned char reg, - unsigned char FAR *buffer, - unsigned long num_bytes); - -static int i2c_write_reg_list_plb( - igd_context_t *context, - unsigned long i2c_bus, - unsigned long i2c_speed, - unsigned long dab, - pd_reg_t *reg_list, - unsigned long flags); - -i2c_dispatch_t i2c_dispatch_plb = { - i2c_read_regs_plb, - i2c_write_reg_list_plb, -}; - - -/*.......................................................................... */ -typedef enum { - - GMBUS_SPEED_50K = 0x0100, - GMBUS_SPEED_100K = 0x0000, - GMBUS_SPEED_400K = 0x0200, - GMBUS_SPEED_1000K = 0x0300, - -} gmbus_speed_t; - -typedef enum { - - SDVOB_ADDR = 0x70, - SDVOC_ADDR = 0x72, - -} sdvo_dev_addr_t; - -typedef enum { - - DDC1_ADDR = 0xA0, - DDC2_ADDR = 0xA2, - -} gmbus_ddc_addr_t; - - -typedef enum { - - GMBUS_PINS_DEDICATED = 1, /* Dedicated Control/GMBUS Pins */ - /* LCTRCLKA, LCTRLCLKB SSC Clock Device */ - GMBUS_PINS_ANALOG = 2, /* Analog DDC */ - GMBUS_PINS_INT_LVDS = 3, /* Alviso : Integrated Digital Panel */ - GMBUS_PINS_SDVO = 5, /* SDVO Registers, DDC, PROM */ - -} gmbus_pins_pair_t; - - -typedef enum { - - I2C_WRITE = 0, - I2C_READ = 1, - -} i2c_bus_dir_t; - -/*.......................................................................... */ -typedef enum { - - SDVO_BUS_PROM = BIT(0), - SDVO_BUS_DDC1 = BIT(1), - SDVO_BUS_DDC2 = BIT(2), - -} sdvo_bus_switch_t; - -#define SDVO_OPCODE_BUS_SWITCH 0x7A - -#define SDVO_INDEX_PARAM_1 0x07 -#define SDVO_INDEX_OPCODE 0x08 -#define SDVO_INDEX_STATUS 0x09 - -#define SDVO_STATUS_SUCCESS 0x01 -#define SDVO_STATUS_PENDING 0x04 - -/*.......................................................................... */ -/* - * In 16-bit, the mmio is a 16-bit pointer, the watcom 1.2 compiler will have - * error if directly convert it to unsigned long. Normally, have to cast it to - * unsigned short first then cast again to unsigned long; then, it will be - * correct. But this type of casting may cause some error in the 32 and 64 bit - * code. Since mmio will be equal to zero for 16-bit code. Add the checking - * for MICRO definition code to correct the macro by remove mmio. - */ -#define READ_GMCH_REG(reg) EMGD_READ32(EMGD_MMIO(mmio) + reg) -#define WRITE_GMCH_REG(reg, data) EMGD_WRITE32(data, EMGD_MMIO(mmio) + reg) - -static int gmbus_init(unsigned char *mmio, unsigned long i2c_bus, - unsigned long i2c_speed); - -static int gmbus_read_edid(unsigned char *mmio, - unsigned long ddc_addr, - unsigned long slave_addr, - unsigned long index, - unsigned long num_bytes, - unsigned char FAR *buffer); - -static int gmbus_read_reg(unsigned char *mmio, - unsigned long slave_addr, - unsigned long index, - unsigned char FAR *data); - -static int gmbus_write_reg(unsigned char *mmio, - unsigned long slave_addr, - unsigned long index, - unsigned char data); - -static int gmbus_set_control_bus_switch(unsigned char *mmio, - unsigned long slave_addr, - gmbus_ddc_addr_t ddc_addr); - -static int gmbus_wait_event_one(unsigned char *mmio, unsigned long bit); -static int gmbus_wait_event_zero(unsigned char *mmio, unsigned long bit); -static int gmbus_error_handler(unsigned char *mmio); - -/*! - * i2c_read_regs_plb is called to read Edid or a single sDVO register - * - * @param context - * @param i2c_bus port->ddc_reg, port->i2c_reg - * @param i2c_speed 50, 100, 400, 1000 (Khz) - * @param dab 0x70/0x72 (sDVO Regs), 0xA0/0xA2 (sDVO/Analog DDC) - * @param reg I2C Reg Index - * @param num_bytes <= 508 - * @param buffer Data read - * - * @return 0 on success - * @return 1 on failure - */ -static int i2c_read_regs_plb(igd_context_t *context, - unsigned long i2c_bus, - unsigned long i2c_speed, - unsigned long dab, - unsigned char reg, - unsigned char FAR *buffer, - unsigned long num_bytes) -{ - unsigned char *mmio = EMGD_MMIO(context->device_context.virt_mmadr); - unsigned long slave_addr; - - if (! gmbus_init(mmio, i2c_bus, i2c_speed)) { - EMGD_DEBUG("Error ! i2c_read_regs_plb : gmbus_init() failed"); - return 1; - } - - /* If the request is to read Edid from sDVO display, find out the */ - /* i2c addres of the sDVO device */ - if (i2c_bus == GMBUS_DVOB_DDC) { - slave_addr = dvob_port_plb.dab; - - } else { - slave_addr = 0; - - } - - switch (i2c_bus) { - case GMBUS_ANALOG_DDC : - case GMBUS_INT_LVDS_DDC : - case GMBUS_DVOB_DDC : - case GMBUS_DVOC_DDC : - if (! gmbus_read_edid(mmio, dab, slave_addr, reg, num_bytes, buffer)) { - - EMGD_DEBUG("Error ! i2c_read_regs_plb : gmbus_read_edid() failed"); - return 1; - } - break; - - case GMBUS_DVO_REG : - if (! gmbus_read_reg(mmio, dab, reg, buffer)) { - - EMGD_DEBUG("Error ! i2c_read_regs_plb : gmbus_read_reg() failed"); - return 1; - } - break; - - default : - EMGD_ERROR("Error ! i2c_read_regs_plb : Invalid i2c_bus=0x%lx", - i2c_bus); - return 1; - } - - return 0; -} - -/*! - * i2c_write_reg_list_plb is called to write a list of i2c registers to sDVO - * device - * - * @param context - * @param i2c_bus NAP_GMBUS_DVOB_DDC/NAP_GMBUS_DVOC_DDC - * @param i2c_speed 1000 Khz - * @param dab 0x70/0x72 - * @param reg_list List of i2c indexes and data, terminated with register index - * set to PD_REG_LIST_END - * - * @return 0 on success - * @return 1 on failure - */ -static int i2c_write_reg_list_plb(igd_context_t *context, - unsigned long i2c_bus, - unsigned long i2c_speed, - unsigned long dab, - pd_reg_t *reg_list, - unsigned long flags) -{ - unsigned char *mmio = EMGD_MMIO(context->device_context.virt_mmadr); - unsigned long reg_num = 0, ddc_addr = 0, slave_addr = 0; - - if (! gmbus_init(mmio, i2c_bus, i2c_speed)) { - - EMGD_DEBUG("Error ! i2c_write_reg_list_plb : gmbus_init() failed"); - return 1; - } - /*If it is SDVO Make sure we issue SDVO command to enable DDC access*/ - if ((i2c_bus == GMBUS_DVOB_DDC) || (i2c_bus == GMBUS_DVOC_DDC)) { - if (i2c_bus == GMBUS_DVOB_DDC) { - slave_addr = dvob_port_plb.dab; - }else if (i2c_bus == GMBUS_DVOC_DDC) { - /* Is DVOC available in PLB? */ - //slave_addr = dvoc_port_plb.dab; - slave_addr = 0; - } - ddc_addr = 0; - if (! gmbus_set_control_bus_switch(mmio, slave_addr, ddc_addr)) { - EMGD_DEBUG("Error ! i2c_write_reg_list_plb : gmbus_set_control_bus_switch()" - " failed"); - return 1; - } - while (reg_list[reg_num].reg != PD_REG_LIST_END) { - - if (! gmbus_write_reg(mmio, dab, reg_list[reg_num].reg, - (unsigned char)reg_list[reg_num].value)) { - - EMGD_DEBUG("Error ! i2c_write_reg_list_plb : gmbus_write_reg() failed, reg_num=%lu", - reg_num); - - return 1; - } - reg_num++; - } - /*...................................................................... */ - /* Issue a Stop Command */ - gmbus_wait_event_one(mmio, HW_WAIT); - WRITE_GMCH_REG(GMBUS1, STO | SW_RDY | ddc_addr); - gmbus_wait_event_one(mmio, HW_RDY); - gmbus_wait_event_zero(mmio, GA); - gmbus_error_handler(mmio); - WRITE_GMCH_REG(GMBUS1, SW_RDY); - WRITE_GMCH_REG(GMBUS1, SW_CLR_INT); - WRITE_GMCH_REG(GMBUS1, 0); - WRITE_GMCH_REG(GMBUS5, 0); - WRITE_GMCH_REG(GMBUS0, 0); - /*...................................................................... */ - return 0; - } - while (reg_list[reg_num].reg != PD_REG_LIST_END) { - - if (! gmbus_write_reg(mmio, dab, reg_list[reg_num].reg, - (unsigned char)reg_list[reg_num].value)) { - - EMGD_DEBUG("Error ! i2c_write_reg_list_plb : gmbus_write_reg() failed, reg_num=%lu", - reg_num); - - return 1; - } - - reg_num++; - } - - return 0; -} - -/*! - * gmbus_init initializes the GMBUS controller with specified bus and speed - * - * @param mmio - * @param i2c_bus sDVO B/C Reg/DDC or Analog DDC - * @param i2c_speed 50/100/400/1000 Khz - * - * @return TRUE(1) on success - * @return FALSE(0) on failure - */ -static int gmbus_init(unsigned char *mmio, unsigned long i2c_bus, - unsigned long i2c_speed) -{ - gmbus_pins_pair_t pin_pair; - gmbus_speed_t bus_speed; - - switch (i2c_bus) { - - case GMBUS_DVO_REG : - case GMBUS_DVOB_DDC : - case GMBUS_DVOC_DDC : - pin_pair = GMBUS_PINS_SDVO; - break; - - case GMBUS_ANALOG_DDC : - pin_pair = GMBUS_PINS_ANALOG; - break; - - case GMBUS_INT_LVDS_DDC : - pin_pair = GMBUS_PINS_INT_LVDS; - break; - - default : - EMGD_ERROR("Error ! gmbus_init : Invalid i2c_bus=0x%lx", i2c_bus); - return 0; - } - - switch (i2c_speed) { - - case 50 : /* Slow speed */ - bus_speed = GMBUS_SPEED_50K; - break; - - case 400 : /* SPD */ - bus_speed = GMBUS_SPEED_400K; - break; - - case 1000 : /* sDVO Registers */ - bus_speed = GMBUS_SPEED_1000K; - break; - - case 100 : /* DDC */ - default : - bus_speed = GMBUS_SPEED_100K; - break; - } - - WRITE_GMCH_REG(GMBUS5, 0); /* Clear the word index reg */ - WRITE_GMCH_REG(GMBUS0, pin_pair | bus_speed); - - return 1; -} - -/*! - * gmbus_wait_event_zero waits for specified GMBUS2 register bit to be deasserted - * - * @param mmio - * @param bit - * - * @return TRUE(1) on success. The bit was deasserted in the specified timeout period - * @return FALSE(0) on failure - */ -static int gmbus_wait_event_zero(unsigned char *mmio, unsigned long bit) -{ - unsigned long i; - unsigned long status; - - for (i = 0; i < 0x1000; i++) { - - status = READ_GMCH_REG(GMBUS2); - - if ((status & bit) == 0) { - - return 1; - } - } - - EMGD_DEBUG("Error ! gmbus_wait_event_zero : Failed : bit=0x%lx, status=0x%lx, forcing reset", - bit, status); - - /* If we are here, that means that the GBMUS is busy or in a bad - * state, the situation was observed - * that the GMBUS never becomes available (idle state) after S3. - * This results in the driver never being able to set the display. - * - * To fix this, we force force a reset of the GMBUS. - */ - WRITE_GMCH_REG(GMBUS1, SW_RDY); - WRITE_GMCH_REG(GMBUS1, SW_CLR_INT); - WRITE_GMCH_REG(GMBUS1, 0); - - return 1; -} - -/*! - * gmbus_wait_event_one wait for specified GMBUS2 register bits to be asserted - * - * @param mmio - * @param bit - * - * @return TRUE(1) on success. The bit was asserted in the specified timeout period - * @return FALSE(0) on failure - */ -static int gmbus_wait_event_one(unsigned char *mmio, unsigned long bit) -{ - unsigned long i; - unsigned long status; - - for (i = 0; i < 0x10000; i++) { - - status = READ_GMCH_REG(GMBUS2); - if ((status & bit) != 0) { - - return 1; - } - } - - EMGD_DEBUG("Error ! gmbus_wait_event_one : Failed : bit=0x%lx, status=0x%lx", - bit, status); - - return 0; -} - -/*! - * gmbus_error_handler attempts to recover from timeout error - * - * @param mmio - * - * @return TRUE(1) error was detected and handled - * @return FALSE(0) there was no error - */ -static int gmbus_error_handler(unsigned char *mmio) -{ - unsigned long status = READ_GMCH_REG(GMBUS2); - - /* Clear the SW_INT, wait for HWRDY and GMBus active (GA) */ - if ((status & HW_BUS_ERR) || (status & HW_TMOUT)) { - - EMGD_DEBUG("Error ! gmbus_error_handler : Resolving error=0x%lx", - status); - - WRITE_GMCH_REG(GMBUS1, SW_RDY); - WRITE_GMCH_REG(GMBUS1, SW_CLR_INT); - WRITE_GMCH_REG(GMBUS1, 0); - - gmbus_wait_event_zero(mmio, GA); - - return 1; /* Handled the error */ - } - - return 0; /* There was no error */ -} - -/*! - * Assemble 32 bit GMBUS1 command - * - * @param slave_addr 0x70/0x72 - * @param index 0 - 256 - * @param num_bytes Bytes to transfer - * @param flags Bits 25-31 of GMBUS1 - * @param i2c_dir I2C_READ / I2C_WRITE - * - * @return The assembled command - */ -static unsigned long gmbus_assemble_command(unsigned long slave_addr, unsigned long index, - unsigned long num_bytes, unsigned long flags, - i2c_bus_dir_t i2c_dir) -{ - unsigned long cmd = flags | ENIDX | ENT | (num_bytes << 16) | (index << 8) | - slave_addr | i2c_dir; - - return cmd; -} - -/*! - * gmbus_send_pkt transmits a block a data to specified i2c slave device - * - * @param mmio - * @param slave_addr I2C device address - * @param index Starting i2c register index - * @param pkt_size 1 - 508 bytes - * @param pkt Bytes to send - * - * @return TRUE(1) if successful in sending the specified number of bytes - * @return FALSE(0) on failure - */ -static int gmbus_send_pkt(unsigned char *mmio, - unsigned long slave_addr, unsigned long index, - unsigned long pkt_size, void *pkt) -{ - unsigned long gmbus1_cmd; - unsigned long bytes_sent; - unsigned long *data; - - if ((pkt_size == 0) || (pkt == NULL) || (pkt_size > 508)) { - - return 0; - } - - data = (unsigned long *)pkt; - - /*...................................................................... */ - gmbus_error_handler(mmio); - - gmbus1_cmd = gmbus_assemble_command(slave_addr, index, pkt_size, - STA, I2C_WRITE); - if (pkt_size <= 4) { - - gmbus1_cmd |= SW_RDY; - } - - /*...................................................................... */ - bytes_sent = 0; - - do { - - WRITE_GMCH_REG(GMBUS3, *data); - - if (bytes_sent == 0) { - - WRITE_GMCH_REG(GMBUS1, gmbus1_cmd); - } - - if (! gmbus_wait_event_one(mmio, HW_RDY)) { - - EMGD_DEBUG("Error ! gmbus_send_pkt : Failed to get HW_RDY, bytes_sent=%ld", - bytes_sent); - - return 0; - } - - if (gmbus_error_handler(mmio)) { - - EMGD_DEBUG("Error ! gmbus_send_pkt : gmbus error, bytes_sent=%ld", - bytes_sent); - - return 0; - } - - data++; - - if (pkt_size >= 4) { - bytes_sent += 4; - - } else { - bytes_sent += pkt_size; - } - - } while (bytes_sent < pkt_size); - - /*...................................................................... */ - if (bytes_sent != pkt_size) { - - return 0; - - } else { - - return 1; - } -} - -/*! - * gmbus_recv_pkt reads a block of data from specified i2c slave device - * - * @param mmio - * @param slave_addr I2C device address - * @param index Starting i2c register index - * @param pkt_size 1 - 508 bytes - * @param pkt Bytes to send - * - * @return TRUE(1) if successful in receiving specified number of bytes - * @return FALSE(0) on failure - */ -static int gmbus_recv_pkt(unsigned char *mmio, - unsigned long slave_addr, unsigned long index, - unsigned long pkt_size, void FAR *pkt) -{ - unsigned long gmbus1_cmd; - unsigned long bytes_rcvd; - unsigned long FAR *data; - - if ((pkt_size == 0) || (pkt == NULL) || (pkt_size > 508)) { - - return 0; - } - - data = (unsigned long FAR *)pkt; - - /*...................................................................... */ - gmbus_error_handler(mmio); - - /* Program the command */ - gmbus1_cmd = gmbus_assemble_command(slave_addr, index, pkt_size, - STA | SW_RDY, I2C_READ); - WRITE_GMCH_REG(GMBUS1, gmbus1_cmd); - - /*...................................................................... */ - bytes_rcvd = 0; - do { - - unsigned long gmbus3_data; - unsigned long bytes_left = pkt_size - bytes_rcvd; - - if (! gmbus_wait_event_one(mmio, HW_RDY)) { - - EMGD_DEBUG("Error ! gmbus_recv_pkt : Failed to get HW_RDY, " - "bytes_rcvd=%ld", bytes_rcvd); - break; - } - - if (gmbus_error_handler(mmio)) { - - EMGD_DEBUG("Error ! gmbus_recv_pkt : gmbus error, bytes_rcvd=%ld", - bytes_rcvd); - break; - } - - gmbus3_data = READ_GMCH_REG(GMBUS3); - - switch (bytes_left) { - - case 1 : - *(unsigned char *)data = (unsigned char)gmbus3_data; - break; - - case 2 : - *(unsigned short *)data = (unsigned short)gmbus3_data; - break; - - case 3 : - { - unsigned char *dest = (unsigned char *)data; - unsigned char *src = (unsigned char *)&(gmbus3_data); - dest[0] = src[0]; - dest[1] = src[1]; - dest[2] = src[2]; - - break; - } - - default : /* >= 4 */ - *data = gmbus3_data; - break; - } - - if (bytes_left > 4) { - bytes_rcvd += 4; - data++; - - } else { - bytes_rcvd += bytes_left; - - } - - } while (bytes_rcvd < pkt_size); - - /*...................................................................... */ - if (bytes_rcvd < pkt_size) { - return 0; - - } else { - return 1; - } -} - -/*! - * gmbus_set_control_bus_switch sends sDVO command to switch i2c bus to read EDID - * or SPD data - * - * @param mmio - * @param slave_addr sDVO device address (0x70/0x72) - * @param ddc_addr DDC1_ADDR/DDC2_ADDR - * - * @return TRUE(1) if successful in sending the opcode - * @return FALSE(0) on failure - */ -static int gmbus_set_control_bus_switch(unsigned char *mmio, - unsigned long slave_addr, - gmbus_ddc_addr_t ddc_addr) -{ - unsigned char data; - sdvo_bus_switch_t bus_switch; - int retry; - - bus_switch = SDVO_BUS_DDC1; - - /*...................................................................... */ - /* Transmit the Arguments */ - if (! gmbus_send_pkt(mmio, slave_addr, SDVO_INDEX_PARAM_1, 1, &bus_switch)) { - - EMGD_DEBUG("Error ! gmbus_set_control_bus_switch : gmbus_send_pkt() failed"); - - return 0; - } - - /*...................................................................... */ - /* Generate I2C stop cycle */ - gmbus_wait_event_one(mmio, HW_WAIT); - WRITE_GMCH_REG(GMBUS1, STO | SW_RDY | slave_addr); - gmbus_wait_event_one(mmio, HW_RDY); - gmbus_wait_event_zero(mmio, GA); - - /*...................................................................... */ - /* Transmit the Opcode */ - data = SDVO_OPCODE_BUS_SWITCH; - if (! gmbus_send_pkt(mmio, slave_addr, SDVO_INDEX_OPCODE, 1, &data)) { - - EMGD_DEBUG("Error ! gmbus_set_control_bus_switch : gmbus_send_pkt(Opcode)" - " failed"); - - return 0; - } - - /*...................................................................... */ - /* Read Status */ - for (retry = 0; retry < 3; retry++) { - if (! gmbus_recv_pkt(mmio, slave_addr, SDVO_INDEX_STATUS, 1, &data)) { - - continue; - } - - if (data != SDVO_STATUS_PENDING) { - - break; - } - } - - /*...................................................................... */ - /* Send Stop */ - gmbus_wait_event_one(mmio, HW_WAIT); - WRITE_GMCH_REG(GMBUS1, STO | SW_RDY | slave_addr); - gmbus_wait_event_one(mmio, HW_RDY); - gmbus_wait_event_zero(mmio, GA); - - /*...................................................................... */ - if (data != SDVO_STATUS_SUCCESS) { - - EMGD_DEBUG("Error ! gmbus_set_control_bus_switch : Opcode Bus Switch failed"); - - return 0; - } - - return 1; -} - -/*! - * gmbus_read_edid reads specified number of Edid data bytes - * - * @param mmio - * @param ddc_addr 0xA0/0xA2 (DDC1/DDC2) - * @param slave_addr 0x70/0x72 (sDVOB, sDVOC), 0 Analog - * @param index i2c register index - * @param num_bytes <= 508 - * @param buffer Edid data read from the display - * - * @return TRUE(1) if successful in reading Edid - * @return FALSE(0) on failure - */ -static int gmbus_read_edid(unsigned char *mmio, - unsigned long ddc_addr, - unsigned long slave_addr, - unsigned long index, - unsigned long num_bytes, - unsigned char FAR *buffer) -{ - int status; - - if ((slave_addr == SDVOB_ADDR) || (slave_addr == SDVOC_ADDR)) { - - if (! gmbus_set_control_bus_switch(mmio, slave_addr, ddc_addr)) { - - EMGD_DEBUG("Error ! gmbus_read_edid : gmbus_set_control_bus_switch()" - " failed"); - - return 0; - } - } else { - /* Reset the bus */ - gmbus_recv_pkt(mmio, ddc_addr, 0, 1, buffer); - } - - status = gmbus_recv_pkt(mmio, ddc_addr, index, num_bytes, buffer); - if (! status) { - - EMGD_DEBUG("Error ! gmbus_read_edid : gmbus_recv_pkt() failed"); - } - - /*...................................................................... */ - /* Issue a Stop Command */ - - gmbus_wait_event_one(mmio, HW_WAIT); - WRITE_GMCH_REG(GMBUS1, STO | SW_RDY | ddc_addr); - gmbus_wait_event_one(mmio, HW_RDY); - - gmbus_wait_event_zero(mmio, GA); - - gmbus_error_handler(mmio); - WRITE_GMCH_REG(GMBUS1, SW_RDY); - WRITE_GMCH_REG(GMBUS1, SW_CLR_INT); - WRITE_GMCH_REG(GMBUS1, 0); - WRITE_GMCH_REG(GMBUS5, 0); - WRITE_GMCH_REG(GMBUS0, 0); - - /*...................................................................... */ - return status; -} - -/*! - * gmbus_read_reg reads one i2c register - * - * @param mmio - * @param slave_addr 0x70/0x72 (sDVOB, sDVOC) - * @param index i2c register index - * @param data register data - * - * @return TRUE(1) if successful in reading the i2c register - * @return FALSE(0) on failure - */ -static int gmbus_read_reg(unsigned char *mmio, - unsigned long slave_addr, - unsigned long index, - unsigned char FAR *data) -{ - unsigned long gmbus1_cmd; - - WRITE_GMCH_REG(GMBUS5, 0x0); /* Clear Word Index register */ - - if (! gmbus_wait_event_zero(mmio, GA)) { - - EMGD_DEBUG("Error ! gmbus_read_reg : Failed to get GA(1)"); - - return 0; - } - - gmbus1_cmd = gmbus_assemble_command(slave_addr, index, 1, - STO | STA, I2C_READ); - WRITE_GMCH_REG(GMBUS1, gmbus1_cmd); - - if (! gmbus_wait_event_zero(mmio, GA)) { - - EMGD_DEBUG("Error ! gmbus_read_reg : Failed to get GA(2)"); - - return 0; - } - - *data = (unsigned char)READ_GMCH_REG(GMBUS3); - - return 1; -} - -/*! - * gmbus_write_reg writes one i2c register - * - * @param mmio - * @param slave_addr 0x70/0x72 (sDVOB, sDVOC) - * @param index i2c register index - * @param data register data - * - * @return TRUE(1) if successful in updating the i2c register - * @return FALSE(0) if failed to update the register - */ -static int gmbus_write_reg(unsigned char *mmio, - unsigned long slave_addr, - unsigned long index, - unsigned char data) -{ - unsigned long gmbus1_cmd; - - WRITE_GMCH_REG(GMBUS5, 0x0); /* Clear Word Index register */ - - if (! gmbus_wait_event_zero(mmio, GA)) { - - EMGD_DEBUG("Error ! gmbus_write_reg : Failed to get GA(1)"); - - return 0; - } - - WRITE_GMCH_REG(GMBUS3, data); - - gmbus1_cmd = gmbus_assemble_command(slave_addr, index, 1, - STO | STA, I2C_WRITE); - WRITE_GMCH_REG(GMBUS1, gmbus1_cmd); - - if (! gmbus_wait_event_zero(mmio, GA)) { - - EMGD_DEBUG("Error ! gmbus_write_reg : Failed to get GA(2)"); - return 0; - } - - return 1; -} - -/*---------------------------------------------------------------------------- - * File Revision History - * $Id: i2c_plb.c,v 1.9 2010/07/23 16:54:50 bpaauwe Exp $ - * $Source: /nfs/fm/proj/eia/cvsroot/koheo/linux/egd_drm/emgd/display/pi/plb/i2c_plb.c,v $ - *---------------------------------------------------------------------------- - */ |