From e09b41010ba33a20a87472ee821fa407a5b8da36 Mon Sep 17 00:00:00 2001 From: José Pekkarinen Date: Mon, 11 Apr 2016 10:41:07 +0300 Subject: These changes are the raw update to linux-4.4.6-rt14. Kernel sources are taken from kernel.org, and rt patch from the rt wiki download page. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During the rebasing, the following patch collided: Force tick interrupt and get rid of softirq magic(I70131fb85). Collisions have been removed because its logic was found on the source already. Change-Id: I7f57a4081d9deaa0d9ccfc41a6c8daccdee3b769 Signed-off-by: José Pekkarinen --- kernel/drivers/staging/sm750fb/ddk750_swi2c.c | 524 +++++++++++++------------- 1 file changed, 259 insertions(+), 265 deletions(-) (limited to 'kernel/drivers/staging/sm750fb/ddk750_swi2c.c') diff --git a/kernel/drivers/staging/sm750fb/ddk750_swi2c.c b/kernel/drivers/staging/sm750fb/ddk750_swi2c.c index 901b3737f..8d644a7cb 100644 --- a/kernel/drivers/staging/sm750fb/ddk750_swi2c.c +++ b/kernel/drivers/staging/sm750fb/ddk750_swi2c.c @@ -15,7 +15,6 @@ #include "ddk750_swi2c.h" #include "ddk750_power.h" - /******************************************************************* * I2C Software Master Driver: * =========================== @@ -55,8 +54,8 @@ ******************************************************************/ /* GPIO pins used for this I2C. It ranges from 0 to 63. */ -static unsigned char g_i2cClockGPIO = DEFAULT_I2C_SCL; -static unsigned char g_i2cDataGPIO = DEFAULT_I2C_SDA; +static unsigned char sw_i2c_clk_gpio = DEFAULT_I2C_SCL; +static unsigned char sw_i2c_data_gpio = DEFAULT_I2C_SDA; /* * Below is the variable declaration for the GPIO pin register usage @@ -70,19 +69,19 @@ static unsigned char g_i2cDataGPIO = DEFAULT_I2C_SDA; */ /* i2c Clock GPIO Register usage */ -static unsigned long g_i2cClkGPIOMuxReg = GPIO_MUX; -static unsigned long g_i2cClkGPIODataReg = GPIO_DATA; -static unsigned long g_i2cClkGPIODataDirReg = GPIO_DATA_DIRECTION; +static unsigned long sw_i2c_clk_gpio_mux_reg = GPIO_MUX; +static unsigned long sw_i2c_clk_gpio_data_reg = GPIO_DATA; +static unsigned long sw_i2c_clk_gpio_data_dir_reg = GPIO_DATA_DIRECTION; /* i2c Data GPIO Register usage */ -static unsigned long g_i2cDataGPIOMuxReg = GPIO_MUX; -static unsigned long g_i2cDataGPIODataReg = GPIO_DATA; -static unsigned long g_i2cDataGPIODataDirReg = GPIO_DATA_DIRECTION; +static unsigned long sw_i2c_data_gpio_mux_reg = GPIO_MUX; +static unsigned long sw_i2c_data_gpio_data_reg = GPIO_DATA; +static unsigned long sw_i2c_data_gpio_data_dir_reg = GPIO_DATA_DIRECTION; /* * This function puts a delay between command */ -static void swI2CWait(void) +static void sw_i2c_wait(void) { /* find a bug: * peekIO method works well before suspend/resume @@ -91,21 +90,17 @@ static void swI2CWait(void) * never finish. * use non-ultimate for loop below is safe * */ -#if 0 + /* Change wait algorithm to use PCI bus clock, it's more reliable than counter loop .. write 0x61 to 0x3ce and read from 0x3cf */ - while(peekIO(0x3ce,0x61) & 0x10); -#else - int i, Temp; - - for(i=0; i<600; i++) - { - Temp = i; - Temp += i; - } -#endif + int i, tmp; + + for (i = 0; i < 600; i++) { + tmp = i; + tmp += i; + } } /* @@ -120,29 +115,29 @@ static void swI2CWait(void) * signal because the i2c will fail when other device try to drive the * signal due to SM50x will drive the signal to always high. */ -void swI2CSCL(unsigned char value) +static void sw_i2c_scl(unsigned char value) { - unsigned long ulGPIOData; - unsigned long ulGPIODirection; - - ulGPIODirection = PEEK32(g_i2cClkGPIODataDirReg); - if (value) /* High */ - { - /* Set direction as input. This will automatically pull the signal up. */ - ulGPIODirection &= ~(1 << g_i2cClockGPIO); - POKE32(g_i2cClkGPIODataDirReg, ulGPIODirection); - } - else /* Low */ - { - /* Set the signal down */ - ulGPIOData = PEEK32(g_i2cClkGPIODataReg); - ulGPIOData &= ~(1 << g_i2cClockGPIO); - POKE32(g_i2cClkGPIODataReg, ulGPIOData); - - /* Set direction as output */ - ulGPIODirection |= (1 << g_i2cClockGPIO); - POKE32(g_i2cClkGPIODataDirReg, ulGPIODirection); - } + unsigned long gpio_data; + unsigned long gpio_dir; + + gpio_dir = PEEK32(sw_i2c_clk_gpio_data_dir_reg); + if (value) { /* High */ + /* + * Set direction as input. This will automatically + * pull the signal up. + */ + gpio_dir &= ~(1 << sw_i2c_clk_gpio); + POKE32(sw_i2c_clk_gpio_data_dir_reg, gpio_dir); + } else { /* Low */ + /* Set the signal down */ + gpio_data = PEEK32(sw_i2c_clk_gpio_data_reg); + gpio_data &= ~(1 << sw_i2c_clk_gpio); + POKE32(sw_i2c_clk_gpio_data_reg, gpio_data); + + /* Set direction as output */ + gpio_dir |= (1 << sw_i2c_clk_gpio); + POKE32(sw_i2c_clk_gpio_data_dir_reg, gpio_dir); + } } /* @@ -157,29 +152,29 @@ void swI2CSCL(unsigned char value) * signal because the i2c will fail when other device try to drive the * signal due to SM50x will drive the signal to always high. */ -void swI2CSDA(unsigned char value) +static void sw_i2c_sda(unsigned char value) { - unsigned long ulGPIOData; - unsigned long ulGPIODirection; - - ulGPIODirection = PEEK32(g_i2cDataGPIODataDirReg); - if (value) /* High */ - { - /* Set direction as input. This will automatically pull the signal up. */ - ulGPIODirection &= ~(1 << g_i2cDataGPIO); - POKE32(g_i2cDataGPIODataDirReg, ulGPIODirection); - } - else /* Low */ - { - /* Set the signal down */ - ulGPIOData = PEEK32(g_i2cDataGPIODataReg); - ulGPIOData &= ~(1 << g_i2cDataGPIO); - POKE32(g_i2cDataGPIODataReg, ulGPIOData); - - /* Set direction as output */ - ulGPIODirection |= (1 << g_i2cDataGPIO); - POKE32(g_i2cDataGPIODataDirReg, ulGPIODirection); - } + unsigned long gpio_data; + unsigned long gpio_dir; + + gpio_dir = PEEK32(sw_i2c_data_gpio_data_dir_reg); + if (value) { /* High */ + /* + * Set direction as input. This will automatically + * pull the signal up. + */ + gpio_dir &= ~(1 << sw_i2c_data_gpio); + POKE32(sw_i2c_data_gpio_data_dir_reg, gpio_dir); + } else { /* Low */ + /* Set the signal down */ + gpio_data = PEEK32(sw_i2c_data_gpio_data_reg); + gpio_data &= ~(1 << sw_i2c_data_gpio); + POKE32(sw_i2c_data_gpio_data_reg, gpio_data); + + /* Set direction as output */ + gpio_dir |= (1 << sw_i2c_data_gpio); + POKE32(sw_i2c_data_gpio_data_dir_reg, gpio_dir); + } } /* @@ -188,55 +183,55 @@ void swI2CSDA(unsigned char value) * Return Value: * The SDA data bit sent by the Slave */ -static unsigned char swI2CReadSDA(void) +static unsigned char sw_i2c_read_sda(void) { - unsigned long ulGPIODirection; - unsigned long ulGPIOData; - - /* Make sure that the direction is input (High) */ - ulGPIODirection = PEEK32(g_i2cDataGPIODataDirReg); - if ((ulGPIODirection & (1 << g_i2cDataGPIO)) != (~(1 << g_i2cDataGPIO))) - { - ulGPIODirection &= ~(1 << g_i2cDataGPIO); - POKE32(g_i2cDataGPIODataDirReg, ulGPIODirection); - } - - /* Now read the SDA line */ - ulGPIOData = PEEK32(g_i2cDataGPIODataReg); - if (ulGPIOData & (1 << g_i2cDataGPIO)) - return 1; - else - return 0; + unsigned long gpio_dir; + unsigned long gpio_data; + unsigned long dir_mask = 1 << sw_i2c_data_gpio; + + /* Make sure that the direction is input (High) */ + gpio_dir = PEEK32(sw_i2c_data_gpio_data_dir_reg); + if ((gpio_dir & dir_mask) != ~dir_mask) { + gpio_dir &= ~(1 << sw_i2c_data_gpio); + POKE32(sw_i2c_data_gpio_data_dir_reg, gpio_dir); + } + + /* Now read the SDA line */ + gpio_data = PEEK32(sw_i2c_data_gpio_data_reg); + if (gpio_data & (1 << sw_i2c_data_gpio)) + return 1; + else + return 0; } /* * This function sends ACK signal */ -static void swI2CAck(void) +static void sw_i2c_ack(void) { - return; /* Single byte read is ok without it. */ + return; /* Single byte read is ok without it. */ } /* * This function sends the start command to the slave device */ -static void swI2CStart(void) +static void sw_i2c_start(void) { - /* Start I2C */ - swI2CSDA(1); - swI2CSCL(1); - swI2CSDA(0); + /* Start I2C */ + sw_i2c_sda(1); + sw_i2c_scl(1); + sw_i2c_sda(0); } /* * This function sends the stop command to the slave device */ -static void swI2CStop(void) +static void sw_i2c_stop(void) { - /* Stop the I2C */ - swI2CSCL(1); - swI2CSDA(0); - swI2CSDA(1); + /* Stop the I2C */ + sw_i2c_scl(1); + sw_i2c_sda(0); + sw_i2c_sda(1); } /* @@ -249,62 +244,60 @@ static void swI2CStop(void) * 0 - Success * -1 - Fail to write byte */ -static long swI2CWriteByte(unsigned char data) +static long sw_i2c_write_byte(unsigned char data) { - unsigned char value = data; - int i; - - /* Sending the data bit by bit */ - for (i=0; i<8; i++) - { - /* Set SCL to low */ - swI2CSCL(0); - - /* Send data bit */ - if ((value & 0x80) != 0) - swI2CSDA(1); - else - swI2CSDA(0); - - swI2CWait(); - - /* Toggle clk line to one */ - swI2CSCL(1); - swI2CWait(); - - /* Shift byte to be sent */ - value = value << 1; - } - - /* Set the SCL Low and SDA High (prepare to get input) */ - swI2CSCL(0); - swI2CSDA(1); - - /* Set the SCL High for ack */ - swI2CWait(); - swI2CSCL(1); - swI2CWait(); - - /* Read SDA, until SDA==0 */ - for(i=0; i<0xff; i++) - { - if (!swI2CReadSDA()) - break; - - swI2CSCL(0); - swI2CWait(); - swI2CSCL(1); - swI2CWait(); - } - - /* Set the SCL Low and SDA High */ - swI2CSCL(0); - swI2CSDA(1); - - if (i<0xff) - return 0; - else - return -1; + unsigned char value = data; + int i; + + /* Sending the data bit by bit */ + for (i = 0; i < 8; i++) { + /* Set SCL to low */ + sw_i2c_scl(0); + + /* Send data bit */ + if ((value & 0x80) != 0) + sw_i2c_sda(1); + else + sw_i2c_sda(0); + + sw_i2c_wait(); + + /* Toggle clk line to one */ + sw_i2c_scl(1); + sw_i2c_wait(); + + /* Shift byte to be sent */ + value = value << 1; + } + + /* Set the SCL Low and SDA High (prepare to get input) */ + sw_i2c_scl(0); + sw_i2c_sda(1); + + /* Set the SCL High for ack */ + sw_i2c_wait(); + sw_i2c_scl(1); + sw_i2c_wait(); + + /* Read SDA, until SDA==0 */ + for (i = 0; i < 0xff; i++) { + if (!sw_i2c_read_sda()) + break; + + sw_i2c_scl(0); + sw_i2c_wait(); + sw_i2c_scl(1); + sw_i2c_wait(); + } + + /* Set the SCL Low and SDA High */ + sw_i2c_scl(0); + sw_i2c_sda(1); + + if (i < 0xff) + return 0; + else + return -1; } /* @@ -317,206 +310,207 @@ static long swI2CWriteByte(unsigned char data) * Return Value: * One byte data read from the Slave device */ -static unsigned char swI2CReadByte(unsigned char ack) +static unsigned char sw_i2c_read_byte(unsigned char ack) { - int i; - unsigned char data = 0; + int i; + unsigned char data = 0; - for(i=7; i>=0; i--) - { - /* Set the SCL to Low and SDA to High (Input) */ - swI2CSCL(0); - swI2CSDA(1); - swI2CWait(); + for (i = 7; i >= 0; i--) { + /* Set the SCL to Low and SDA to High (Input) */ + sw_i2c_scl(0); + sw_i2c_sda(1); + sw_i2c_wait(); - /* Set the SCL High */ - swI2CSCL(1); - swI2CWait(); + /* Set the SCL High */ + sw_i2c_scl(1); + sw_i2c_wait(); - /* Read data bits from SDA */ - data |= (swI2CReadSDA() << i); - } + /* Read data bits from SDA */ + data |= (sw_i2c_read_sda() << i); + } - if (ack) - swI2CAck(); + if (ack) + sw_i2c_ack(); - /* Set the SCL Low and SDA High */ - swI2CSCL(0); - swI2CSDA(1); + /* Set the SCL Low and SDA High */ + sw_i2c_scl(0); + sw_i2c_sda(1); - return data; + return data; } /* * This function initializes GPIO port for SW I2C communication. * * Parameters: - * i2cClkGPIO - The GPIO pin to be used as i2c SCL - * i2cDataGPIO - The GPIO pin to be used as i2c SDA + * clk_gpio - The GPIO pin to be used as i2c SCL + * data_gpio - The GPIO pin to be used as i2c SDA * * Return Value: * -1 - Fail to initialize the i2c * 0 - Success */ -static long swI2CInit_SM750LE(unsigned char i2cClkGPIO, - unsigned char i2cDataGPIO) +static long sm750le_i2c_init(unsigned char clk_gpio, + unsigned char data_gpio) { - int i; + int i; - /* Initialize the GPIO pin for the i2c Clock Register */ - g_i2cClkGPIODataReg = GPIO_DATA_SM750LE; - g_i2cClkGPIODataDirReg = GPIO_DATA_DIRECTION_SM750LE; + /* Initialize the GPIO pin for the i2c Clock Register */ + sw_i2c_clk_gpio_data_reg = GPIO_DATA_SM750LE; + sw_i2c_clk_gpio_data_dir_reg = GPIO_DATA_DIRECTION_SM750LE; - /* Initialize the Clock GPIO Offset */ - g_i2cClockGPIO = i2cClkGPIO; + /* Initialize the Clock GPIO Offset */ + sw_i2c_clk_gpio = clk_gpio; - /* Initialize the GPIO pin for the i2c Data Register */ - g_i2cDataGPIODataReg = GPIO_DATA_SM750LE; - g_i2cDataGPIODataDirReg = GPIO_DATA_DIRECTION_SM750LE; + /* Initialize the GPIO pin for the i2c Data Register */ + sw_i2c_data_gpio_data_reg = GPIO_DATA_SM750LE; + sw_i2c_data_gpio_data_dir_reg = GPIO_DATA_DIRECTION_SM750LE; - /* Initialize the Data GPIO Offset */ - g_i2cDataGPIO = i2cDataGPIO; + /* Initialize the Data GPIO Offset */ + sw_i2c_data_gpio = data_gpio; - /* Note that SM750LE don't have GPIO MUX and power is always on */ + /* Note that SM750LE don't have GPIO MUX and power is always on */ - /* Clear the i2c lines. */ - for(i=0; i<9; i++) - swI2CStop(); + /* Clear the i2c lines. */ + for (i = 0; i < 9; i++) + sw_i2c_stop(); - return 0; + return 0; } /* * This function initializes the i2c attributes and bus * * Parameters: - * i2cClkGPIO - The GPIO pin to be used as i2c SCL - * i2cDataGPIO - The GPIO pin to be used as i2c SDA + * clk_gpio - The GPIO pin to be used as i2c SCL + * data_gpio - The GPIO pin to be used as i2c SDA * * Return Value: * -1 - Fail to initialize the i2c * 0 - Success */ -long swI2CInit( - unsigned char i2cClkGPIO, - unsigned char i2cDataGPIO +long sm750_sw_i2c_init( + unsigned char clk_gpio, + unsigned char data_gpio ) { - int i; + int i; - /* Return 0 if the GPIO pins to be used is out of range. The range is only from [0..63] */ - if ((i2cClkGPIO > 31) || (i2cDataGPIO > 31)) - return -1; + /* + * Return 0 if the GPIO pins to be used is out of range. The + * range is only from [0..63] + */ + if ((clk_gpio > 31) || (data_gpio > 31)) + return -1; - if (getChipType() == SM750LE) - return swI2CInit_SM750LE(i2cClkGPIO, i2cDataGPIO); + if (getChipType() == SM750LE) + return sm750le_i2c_init(clk_gpio, data_gpio); - /* Initialize the GPIO pin for the i2c Clock Register */ - g_i2cClkGPIOMuxReg = GPIO_MUX; - g_i2cClkGPIODataReg = GPIO_DATA; - g_i2cClkGPIODataDirReg = GPIO_DATA_DIRECTION; + /* Initialize the GPIO pin for the i2c Clock Register */ + sw_i2c_clk_gpio_mux_reg = GPIO_MUX; + sw_i2c_clk_gpio_data_reg = GPIO_DATA; + sw_i2c_clk_gpio_data_dir_reg = GPIO_DATA_DIRECTION; - /* Initialize the Clock GPIO Offset */ - g_i2cClockGPIO = i2cClkGPIO; + /* Initialize the Clock GPIO Offset */ + sw_i2c_clk_gpio = clk_gpio; - /* Initialize the GPIO pin for the i2c Data Register */ - g_i2cDataGPIOMuxReg = GPIO_MUX; - g_i2cDataGPIODataReg = GPIO_DATA; - g_i2cDataGPIODataDirReg = GPIO_DATA_DIRECTION; + /* Initialize the GPIO pin for the i2c Data Register */ + sw_i2c_data_gpio_mux_reg = GPIO_MUX; + sw_i2c_data_gpio_data_reg = GPIO_DATA; + sw_i2c_data_gpio_data_dir_reg = GPIO_DATA_DIRECTION; - /* Initialize the Data GPIO Offset */ - g_i2cDataGPIO = i2cDataGPIO; + /* Initialize the Data GPIO Offset */ + sw_i2c_data_gpio = data_gpio; - /* Enable the GPIO pins for the i2c Clock and Data (GPIO MUX) */ - POKE32(g_i2cClkGPIOMuxReg, - PEEK32(g_i2cClkGPIOMuxReg) & ~(1 << g_i2cClockGPIO)); - POKE32(g_i2cDataGPIOMuxReg, - PEEK32(g_i2cDataGPIOMuxReg) & ~(1 << g_i2cDataGPIO)); + /* Enable the GPIO pins for the i2c Clock and Data (GPIO MUX) */ + POKE32(sw_i2c_clk_gpio_mux_reg, + PEEK32(sw_i2c_clk_gpio_mux_reg) & ~(1 << sw_i2c_clk_gpio)); + POKE32(sw_i2c_data_gpio_mux_reg, + PEEK32(sw_i2c_data_gpio_mux_reg) & ~(1 << sw_i2c_data_gpio)); - /* Enable GPIO power */ - enableGPIO(1); + /* Enable GPIO power */ + enableGPIO(1); - /* Clear the i2c lines. */ - for(i=0; i<9; i++) - swI2CStop(); + /* Clear the i2c lines. */ + for (i = 0; i < 9; i++) + sw_i2c_stop(); - return 0; + return 0; } /* * This function reads the slave device's register * * Parameters: - * deviceAddress - i2c Slave device address which register + * addr - i2c Slave device address which register * to be read from - * registerIndex - Slave device's register to be read + * reg - Slave device's register to be read * * Return Value: * Register value */ -unsigned char swI2CReadReg( - unsigned char deviceAddress, - unsigned char registerIndex +unsigned char sm750_sw_i2c_read_reg( + unsigned char addr, + unsigned char reg ) { - unsigned char data; + unsigned char data; - /* Send the Start signal */ - swI2CStart(); + /* Send the Start signal */ + sw_i2c_start(); - /* Send the device address */ - swI2CWriteByte(deviceAddress); + /* Send the device address */ + sw_i2c_write_byte(addr); - /* Send the register index */ - swI2CWriteByte(registerIndex); + /* Send the register index */ + sw_i2c_write_byte(reg); - /* Get the bus again and get the data from the device read address */ - swI2CStart(); - swI2CWriteByte(deviceAddress + 1); - data = swI2CReadByte(1); + /* Get the bus again and get the data from the device read address */ + sw_i2c_start(); + sw_i2c_write_byte(addr + 1); + data = sw_i2c_read_byte(1); - /* Stop swI2C and release the bus */ - swI2CStop(); + /* Stop swI2C and release the bus */ + sw_i2c_stop(); - return data; + return data; } /* * This function writes a value to the slave device's register * * Parameters: - * deviceAddress - i2c Slave device address which register + * addr - i2c Slave device address which register * to be written - * registerIndex - Slave device's register to be written + * reg - Slave device's register to be written * data - Data to be written to the register * * Result: * 0 - Success * -1 - Fail */ -long swI2CWriteReg( - unsigned char deviceAddress, - unsigned char registerIndex, - unsigned char data +long sm750_sw_i2c_write_reg( + unsigned char addr, + unsigned char reg, + unsigned char data ) { - long returnValue = 0; + long ret = 0; - /* Send the Start signal */ - swI2CStart(); + /* Send the Start signal */ + sw_i2c_start(); - /* Send the device address and read the data. All should return success - in order for the writing processed to be successful - */ - if ((swI2CWriteByte(deviceAddress) != 0) || - (swI2CWriteByte(registerIndex) != 0) || - (swI2CWriteByte(data) != 0)) - { - returnValue = -1; - } + /* Send the device address and read the data. All should return success + in order for the writing processed to be successful + */ + if ((sw_i2c_write_byte(addr) != 0) || + (sw_i2c_write_byte(reg) != 0) || + (sw_i2c_write_byte(data) != 0)) { + ret = -1; + } - /* Stop i2c and release the bus */ - swI2CStop(); + /* Stop i2c and release the bus */ + sw_i2c_stop(); - return returnValue; + return ret; } -- cgit 1.2.3-korg