[i2c] [PATCH] I2C bus driver for Philips ARM boards
Vitaly Wool
vwool at ru.mvista.com
Tue Jul 4 09:50:46 CEST 2006
Hello Jean,
thanks for the thourough and comprehensive review!
I'd agree with most of your comments/proposals, but there're some I'd
like to argue/comment a bit.
> The name "i2c-pnx" is a bit too generic IMHO. What if another PNX board
> is later released with a different I2C implementation?
>
All Philips boards that either use or going to use Linux have very
similar I2C IP blocks. Everything that might differ is put into
arch-specific.
>> + *
>> + * Provides i2c support for PNX010x/PNX4008.
>>
>
> Mentioning that these are Philips board would be welcome.
>
Ok, though I can't help saying that P stands for Philips in 'PNX'. ;-)
> You could use I2C_SMBUS_READ and I2C_SMBUS_WRITE instead of inventing
> your own rw_bit.
>
rw_bit is a control bit of Tx register, so I don't think it's really
reasonable here.
>> + if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_tdi) {
>> + printk(KERN_WARNING
>> + "%s: TDI still set ... clearing now.\n",
>> + adap->name);
>> + stat |= mstatus_tdi;
>>
>
> This doesn't seem to have any effect, as you just checked that this bit
> was already set.
>
No, it's cleared by writing a '1' to it.
>> + iowrite32(stat, I2C_REG_STS(alg_data));
>> + }
>> + if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_afi) {
>> + printk(KERN_WARNING
>> + "%s: AFI still set ... clearing now.\n",
>> + adap->name);
>> + stat |= mstatus_afi;
>>
>
> Same here.
>
>
Ditto :)
>
>
>> +
>> + /* Cleanup to be sure ... */
>> + alg_data->mif.buf = NULL;
>> + alg_data->mif.len = 0;
>>
>
> Useless as far as I can see, but well...
>
>
>> +
>> + /* Release sem */
>> + up(&alg_data->mif.sem);
>> + dev_dbg(&adap->dev, "%s(): exiting, stat = %x\n",
>> + __FUNCTION__, ioread32(I2C_REG_STS(alg_data)));
>> +
>> + if (completed != num)
>> + return ((rc < 0) ? rc : -EREMOTEIO);
>> +
>> + return num;
>> +}
>>
>
> When sending more than once message at once, the I2C protocol says
> that you should have a "repeated start" condition between messages. It
> seems that your driver is instead sending a stop condition followed by
> a start condition, which is different. Please check the hardware
> documentation for your device and the I2C specification, you are
> probably not sending the correct signals on the wire (could be checked
> with an oscilloscope.) It may still work in some cases, but some
> devices may not accept the alternative (start/stop) formatting.
>
I don't think that I'm following you here. AFAI can see, stop is issued
only for zero-sized transfers or when a NAK is received what complied to
the IP block interface specification.
>> + i2c_pnx->suspend = plat_data->suspend;
>> + i2c_pnx->resume = plat_data->resume;
>> + i2c_pnx->calculate_input_freq = plat_data->calculate_input_freq;
>> + i2c_pnx->set_clock_run = plat_data->set_clock_run;
>> + i2c_pnx->set_clock_stop = plat_data->set_clock_stop;
>>
>
> Why don't you simply store a pointer to the platform data, rather than
> duplicating every entry?
>
Hmmm, isn't it released after bootup?
>
>> + i2c_pnx->adapter = plat_data->adapter;
>> + platform_set_drvdata(pdev, i2c_pnx);
>> +
>> + if (i2c_pnx->calculate_input_freq)
>> + freq_mhz = i2c_pnx->calculate_input_freq(pdev);
>> + else {
>> + freq_mhz = 13;
>>
>
> Maybe define e.g. PNX_DEFAULT_FREQ at the top of the file?
>
>> + * the deglitching filter length. In this example, n = 7, since
>> + * eight bits are needed to hold the clock divider count.
>> + */
>>
>
> I don't understand the explanation, especially the last sentence. How
> do you go from 98 to 7?
>
Oops, sorry, 'n' parameter is not used any more. Anyway, this was not
the same thing as the one that should be 98 :)
>> + iounmap((void *)alg_data->ioaddr);
>>
>
> Unnecessary cast?
>
ioaddr is u32
>> +MODULE_LICENSE("GPL");
>> +
>> +subsys_initcall(i2c_adap_pnx_init);
>>
>
> Why not simply module_init?
>
I2C needs to be initialized before USB, as USB IP block is configured
via I2C.
>> + struct i2c_pnx_mif mif;
>> +};
>> +
>> +#define TIMEOUT (2*(HZ))
>> +#define I2C_PNX_SPEED_KHZ 100
>> +#define I2C_BLOCK_SIZE 0x100
>>
>
> "I2C_BLOCK_SIZE" is way too generic for something which is specific to
> your device. Also, it's the size of the I/O region, so "BLOCK" doesn't
> fit very well. I2C_PNX_REGION_SIZE maybe?
>
> This is also an implementation detail, platform doesn't need to know,
> so this define should be moved to the driver itself (i2c-pnx.c). Same
> for I2C_PNX_SPEED_KHZ.
>
No, these two depend more on the IP block than on the implementation for
a particular board.
>> +
>> +void __init pnx4008_register_i2c_devices(void)
>> +{
>> + platform_add_devices(devices, ARRAY_SIZE(devices));
>> +}
>>
>
> This function not called anywhere?
>
It's gonna be called from arch/arm/mach-pnx4008/core.c which is not
included into this patch as it will go to rmk for approval. :)
Best regards,
Vitaly
More information about the i2c
mailing list