Re: [PATCH] mfd: pxa-w1: MFD driver for PXA 1wire control + DS1WM chip

From: Jean-Francois Dagenais
Date: Mon Mar 14 2011 - 15:55:55 EST



On Mar 14, 2011, at 8:34, Haojian Zhuang wrote:

>
>
>> -----Original Message-----
>> From: Samuel Ortiz [mailto:sameo@xxxxxxxxxxxxxxx]
>> Sent: 2011å3æ14æ 7:29 PM
>> To: Haojian Zhuang
>> Cc: johnpol@xxxxxxxxxxx; a.zummo@xxxxxxxxxxxx; lrg@xxxxxxxxxxxxxxx;
>> broonie@xxxxxxxxxxxxxxxxxxxxxxxxxxx; dmitry.torokhov@xxxxxxxxx;
>> dtor@xxxxxxx; rpurdie@xxxxxxxxx; linux-kernel@xxxxxxxxxxxxxxx
>> Subject: Re: [PATCH] mfd: pxa-w1: MFD driver for PXA 1wire control +
>> DS1WM chip
>>
>> Hi Haojian,
>>
>> On Mon, Mar 07, 2011 at 11:43:20PM +0800, Haojian Zhuang wrote:
>>> This driver provides registers and IRQ of PXA3xx chips to the ds1wm
>> driver.
>> Why is this an MFD driver ?
>>
>> Cheers,
>> Samuel.
>>
>> --
>> Intel Open Source Technology Centre
>> http://oss.intel.com/
>
> Hi Samuel,
>
> Because there's already a DS1WM driver in drivers/w1/masters/ds1wm.c. In PXA silicons, W1 controler is compatible with this driver. So we implement it as MFD driver, like htc-pasic3.c.
>
> Best Regards
> Haojian--
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
I successfully made this driver work with a ds1wm core inside a virtex5 interfaced through PCI express. The base address of the ds1wm is at a certain offset in the BAR0 of the virtex5. We used a shared interrupt for the ds1wm and the other function our virtex5 does. This is on a x86 platform. I posted a couple of patches last week which added multi-slave search support to the existing ds1wm driver.

look for [w1 PATCHES 3/3] Complete the 1-wire (w1) ds1wm driver search algo

I declare the presence of the ds1wm from my pci_probe of the FPGA device.

static int ds1wm_enable(struct platform_device *pdev)
{
struct MYSTRUCT* pMyDevStruct = dev_get_drvdata(pdev->dev.parent);
u32* address = pHudDev->bar0KernAddr + REG_OFFSET_RESET;
... custom stuff you need to do to make the ds1wm power up
return 0;
}

static int ds1wm_disable(struct platform_device *pdev)
{
... undo what you did in enable.
return 0;
}
#define REG_1_WIRE_BASE 0xXX
static struct ds1wm_driver_data ds1wm_pdata = {
.active_high = 1,
.clock_rate = 125000000 // PCIe transaction clock
};


static struct resource ds1wm_resources[] = {
[0] = {
.start = REG_1_WIRE_BASE,
.end = REG_1_WIRE_BASE + (5*sizeof(int)), // that's 5 registers each on a 32 bit address, we omit the 6th one, i.e. control reg
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 0, // cell define as offset from parent base resource, i.e. 0 means same
.end = 0,
.flags = IORESOURCE_IRQ,
},
};

static struct mfd_cell ds1wm_cell = {
.name = "ds1wm",
.enable = ds1wm_enable,
.disable = ds1wm_disable,
.driver_data = &ds1wm_pdata,
.num_resources = 2,
.resources = ds1wm_resources,
};

[...] in my pci_probe() [...]
ds1wm_cell.platform_data = &ds1wm_cell;
ds1wm_cell.data_size = sizeof(ds1wm_cell);
PDEBUG( "adding ds1wm core in mfd subsys, irq: %d\n", pPciDev->irq);
if(0 > mfd_add_devices(&pPciDev->dev, 0, &ds1wm_cell, 1, &pPciDev->resource[0], pPciDev->irq))
{
printk(KERN_CRIT PRINTK_ID "%s failed to add ds1wm \n", pHudDev->hwDeviceName);
goto cancel_and_exit;
}
PDEBUG( "ds1wm core added to mfd subsys\n");

GOOD LUCK!

FYI, here's the intro I had for these patches:
===================

The first patch add generic functionnality to w1_io for Resume Command [A5h]
lots of slaves support. I found it useful for multi-commands/reset workflows
with the same slave on a multi-slave bus.

This DS2408 w1 slave driver is not complete for all the
features of the chip, but its sufficient if you use it as
a simple IO expander. Enjoy!

The ds1wm had Kconfig dependencies towards ARM && HAVE_CLK. I took them
out since I was using the ds1wm on an x86_64 platform (ds1wm in a FPGA through
pcie) and found them irrelevant.

The clock freq/divisors at the top of ds1wm.c did not have the MSB set to 1.
This bit is CLK_EN which turns the whole prescaler and dividers on. The driver
never mentionned this bit either, so I just included this bit right in the table
entries. I also took the liberty to add a couple of entries to the table. The
spec doesn't explicitely mentions these possibilities but the description and
examination of the core shows the prescalers & dividers can be used for more
than the table explicitely shows. The table I enlarged still doesn't cover all
possibilities, but it's a good start.

I also made a few tweaks to a couple of the read and write algorithms which
made sense while I had my head very deep in the ds1wm documentation. We stressed
it a lot with 10+ slaves on the bus, many ds2408, ds2431 and ds2433 at the same
time doing extensive interaction. It proved quite stable in our production
environment.--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/