On Friday 10 June 2011, Ying-Chun Liu (PaulLiu) wrote:
>
> +config PMIC_DIALOG
> + bool "Support Dialog Semiconductor PMIC"
> + depends on I2C=y
> + depends on SPI=y
> + select MFD_CORE
> + help
> + Support for Dialog semiconductor PMIC chips.
> + Use the options provided to support the desired PMIC's.
> +choice
> + prompt "Chip Type"
> + depends on PMIC_DIALOG
> +config PMIC_DA9052
> + bool "Support Dialog Semiconductor DA9052 PMIC"
> + help
> + Support for Dialog semiconductor DA9052 PMIC with inbuilt
> + SPI & I2C connectivities.
> + This driver provides common support for accessing the device,
> + additional drivers must be enabled in order to use the
> + functionality of the device.
> +config PMIC_DA9053AA
> + bool "Support Dialog Semiconductor DA9053 AA PMIC"
> + help
> + Support for Dialog semiconductor DA9053 AA PMIC with inbuilt
> + SPI & I2C connectivities.
> + This driver provides common support for accessing the device,
> + additional drivers must be enabled in order to use the
> + functionality of the device.
> +config PMIC_DA9053Bx
> + bool "Support Dialog Semiconductor DA9053 BA/BB PMIC"
> + help
> + Support for Dialog semiconductor DA9053 BA/BB PMIC with inbuilt
> + SPI & I2C connectivities.
> + This driver provides common support for accessing the device,
> + additional drivers must be enabled in order to use the
> + functionality of the device.
> +endchoice
This can use a few lines of whitespace.
Why do you need a choice statement here? I would think that you need
to be able to build a kernel with all three chips builtin at the same
time, in order to run on all boards that have one of them.
> +#define SUCCESS 0
> +#define FAILURE 1
Remove these. We use negative error codes from linux/errno.h to indicate
failure.
> +struct da9052_eh_nb eve_nb_array[EVE_CNT];
Why do you need this array? Better keep the information local to your
devices.
> +static struct da9052_ssc_ops ssc_ops;
Make this const and statically initialize it with the functions instead
of assigning the function pointers at runtime.
> +struct mutex manconv_lock;
use DEFINE_MUTEX
> +static struct semaphore eve_nb_array_lock;
No new semaphores. Use a mutex.
> +void da9052_lock(struct da9052 *da9052)
> +{
> + mutex_lock(&da9052->ssc_lock);
> +}
> +EXPORT_SYMBOL(da9052_lock);
> +
> +void da9052_unlock(struct da9052 *da9052)
> +{
> + mutex_unlock(&da9052->ssc_lock);
> +}
> +EXPORT_SYMBOL(da9052_unlock);
use EXPORT_SYMBOL_GPL()
> +int da9052_ssc_write(struct da9052 *da9052, struct da9052_ssc_msg *sscmsg)
> +{
> + int ret = 0;
> +
> + /* Reg address should be a valid address on PAGE0 or PAGE1 */
> + if ((sscmsg->addr < DA9052_PAGE0_REG_START) ||
> + (sscmsg->addr > DA9052_PAGE1_REG_END) ||
> + ((sscmsg->addr > DA9052_PAGE0_REG_END) &&
> + (sscmsg->addr < DA9052_PAGE1_REG_START)))
> + return INVALID_REGISTER;
return a proper error code, e.g. "-EINVAL"
> + ret = ssc_ops.write(da9052, sscmsg);
Take the ops from the device, e.g.
ret = da9052->scc_ops.write(da9052, sscmsg);
> +static irqreturn_t da9052_eh_isr(int irq, void *dev_id)
> +{
> + struct da9052 *da9052 = dev_id;
> + /* Schedule work to be done */
> + schedule_work(&da9052->eh_isr_work);
> + /* Disable IRQ */
> + disable_irq_nosync(da9052->irq);
> + return IRQ_HANDLED;
> +}
You shouldn't need to disable the interrupt if you don't clear the event
bits at the source.
> + ret = da9052_add_subdevice(da9052, "da9052-rtc");
> + if (ret)
> + return ret;
> + ret = da9052_add_subdevice(da9052, "da9052-onkey");
> + if (ret)
> + return ret;
> +
> + ret = da9052_add_subdevice(da9052, "WLED-1");
> + if (ret)
> + return ret;
> +
> + ret = da9052_add_subdevice(da9052, "WLED-2");
> + if (ret)
> + return ret;
> +
> + ret = da9052_add_subdevice(da9052, "WLED-3");
> + if (ret)
> + return ret;
Why not add them all at once?
> + /* Initialize mutex required for ADC Manual read */
> + mutex_init(&manconv_lock);
> +
> + /* Initialize NB array lock */
> + sema_init(&eve_nb_array_lock, 1);
these are not needed if you use DEFINE_MUTEX
> + /* Assign the read-write function pointers */
> + da9052->read = da9052_ssc_read;
> + da9052->write = da9052_ssc_write;
> + da9052->read_many = da9052_ssc_read_many;
> + da9052->write_many = da9052_ssc_write_many;
> +
> + if (SPI == da9052->connecting_device && ssc_ops.write == NULL) {
> + /* Assign the read/write pointers to SPI/read/write */
> + ssc_ops.write = da9052_spi_write;
> + ssc_ops.read = da9052_spi_read;
> + ssc_ops.write_many = da9052_spi_write_many;
> + ssc_ops.read_many = da9052_spi_read_many;
> + } else if (I2C == da9052->connecting_device
> + && ssc_ops.write == NULL) {
> + /* Assign the read/write pointers to SPI/read/write */
> + ssc_ops.write = da9052_i2c_write;
> + ssc_ops.read = da9052_i2c_read;
> + ssc_ops.write_many = da9052_i2c_write_many;
> + ssc_ops.read_many = da9052_i2c_read_many;
> + } else
> + return -1;
Just define two different operations structures for the difference.
> diff --git a/drivers/mfd/da9052-i2c.c b/drivers/mfd/da9052-i2c.c
> new file mode 100644
> index 0000000..5fd966a
> --- /dev/null
> +++ b/drivers/mfd/da9052-i2c.c
> +
> +static struct da9052 *da9052_i2c;
A static pointer should not be necessary, just pass the device around to
all the functions. This is especially necessary if you have more than
one instance.
> + /* Test spi connectivity by performing read of the GPIO_0-1 register */
> + if (0 != da9052_i2c_read(da9052_i2c, &msg)) {
Do comparisons like
if (da9052_i2c_read(da9052_i2c, &msg) != 0)
or better
if (da9052_i2c_read(da9052_i2c, &msg))
> + printk(KERN_DEBUG "da9052_i2c_is_connected - "\
> + "i2c read failed.............\n");
> + return -1;
> + } else {
> + printk(KERN_DEBUG "da9052_i2c_is_connected - "\
> + "i2c read success..............\n");
> + return 0;
> + }
Use proper error codes, don't return -1.
> + /* Validate I2C connectivity */
> + if (I2C_CONNECTED == da9052_i2c_is_connected()) {
> + /* I2C is connected */
> + da9052_i2c->connecting_device = I2C;
> + if (0 != da9052_ssc_init(da9052_i2c))
> + return -ENODEV;
> + } else {
> + return -ENODEV;
> + }
See above for the comparisons.
Make sure you free the memory in the error path. The best way
to do that is to have a "goto error" statement to a place
where you free the memory and return.
> + /* printk("Exiting da9052_i2c_probe.....\n"); */
Remove stale comments like this.
> +
> +struct da9052 *da9052_spi;
> +
> +#define SPI_CONNECTED 0
> +
> +static int da9052_spi_is_connected(void)
> +{
> +
> + struct da9052_ssc_msg msg;
> +
> + /* printk("Entered da9052_spi_is_connected.............\n"); */
> +
> + msg.addr = DA9052_INTERFACE_REG;
> +
> + /* Test spi connectivity by performing read of the GPIO_0-1 register
> + and then verify the read value*/
> + if (0 != da9052_spi_read(da9052_spi, &msg)) {
> + printk(KERN_DEBUG "da9052_spi_is_connected - "\
> + "spi read failed.............\n");
> + return -1;
> + } else if (0x88 != msg.data) {
> + printk(KERN_DEBUG "da9052_spi_is_connected - " \
> + "spi read failed. Msg data =%x ..............\n",
> + msg.data);
> + return -1;
Same comments as above apply.
> +int da9052_spi_write(struct da9052 *da9052, struct da9052_ssc_msg *msg)
> +{
The functions should probably all be static. Just pass the ssc_ops to
da9052_ssc_init.
Arnd
_______________________________________________
linaro-dev mailing list
[email protected]
http://lists.linaro.org/mailman/listinfo/linaro-dev