diff mbox

[02/12] i2c: si570: merge support for si570 clock generator

Message ID 1387865711-23124-3-git-send-email-daniel.sangorrin@toshiba.co.jp (mailing list archive)
State New, archived
Headers show

Commit Message

Daniel Sangorrin Dec. 24, 2013, 6:15 a.m. UTC
From: Rob Armstrong <ra@xilinx.com>

This merges support for the si5790 clock generator from the Xilinx
repository (commit efc27505715e64526653f35274717c0fc56491e3 from
master branch).

Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp>
Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp>
---
 drivers/misc/Kconfig      |  10 +
 drivers/misc/Makefile     |   1 +
 drivers/misc/si570.c      | 576 ++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/i2c/si570.h |  31 +++
 4 files changed, 618 insertions(+)
 create mode 100644 drivers/misc/si570.c
 create mode 100644 include/linux/i2c/si570.h

Comments

Greg KH Jan. 5, 2014, 10:05 p.m. UTC | #1
On Tue, Dec 24, 2013 at 03:15:01PM +0900, Daniel Sangorrin wrote:
> From: Rob Armstrong <ra@xilinx.com>
> 
> This merges support for the si5790 clock generator from the Xilinx
> repository (commit efc27505715e64526653f35274717c0fc56491e3 from
> master branch).
> 
> Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp>
> Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp>
> ---
>  drivers/misc/Kconfig      |  10 +
>  drivers/misc/Makefile     |   1 +
>  drivers/misc/si570.c      | 576 ++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/i2c/si570.h |  31 +++
>  4 files changed, 618 insertions(+)
>  create mode 100644 drivers/misc/si570.c
>  create mode 100644 include/linux/i2c/si570.h
> 
> diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
> index c002d86..1c9fd72 100644
> --- a/drivers/misc/Kconfig
> +++ b/drivers/misc/Kconfig
> @@ -507,6 +507,16 @@ config USB_SWITCH_FSA9480
>  	  stereo and mono audio, video, microphone and UART data to use
>  	  a common connector port.
>  
> +config SI570
> +	tristate "Silicon Labs Si570 Clock Generator"
> +	depends on I2C && SYSFS
> +	help
> +	  If you say yes here you get support for the Silicon Labs Si570
> +	  digital clock generator.
> +
> +	  To compile this driver as a module, choose M here: the module
> +	  will be called si570
> +
>  config LATTICE_ECP3_CONFIG
>  	tristate "Lattice ECP3 FPGA bitstream configuration via SPI"
>  	depends on SPI && SYSFS
> diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
> index c235d5b..e84bcaa 100644
> --- a/drivers/misc/Makefile
> +++ b/drivers/misc/Makefile
> @@ -50,6 +50,7 @@ obj-y				+= carma/
>  obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o
>  obj-$(CONFIG_ALTERA_STAPL)	+=altera-stapl/
>  obj-$(CONFIG_INTEL_MEI)		+= mei/
> +obj-$(CONFIG_SI570)		+= si570.o
>  obj-$(CONFIG_VMWARE_VMCI)	+= vmw_vmci/
>  obj-$(CONFIG_LATTICE_ECP3_CONFIG)	+= lattice-ecp3-config.o
>  obj-$(CONFIG_SRAM)		+= sram.o
> diff --git a/drivers/misc/si570.c b/drivers/misc/si570.c
> new file mode 100644
> index 0000000..30d8288
> --- /dev/null
> +++ b/drivers/misc/si570.c
> @@ -0,0 +1,576 @@
> +/*
> + * Driver for Silicon Labs Si570/Si571 Programmable XO/VCXO
> + *
> + * Copyright (C) 2010, 2011 Ericsson AB.
> + * Copyright (C) 2011 Guenter Roeck.
> + *
> + * Author: Guenter Roeck <guenter.roeck@ericsson.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that 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.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/jiffies.h>
> +#include <linux/i2c.h>
> +#include <linux/err.h>
> +#include <linux/mutex.h>
> +#include <linux/delay.h>
> +#include <linux/log2.h>
> +#include <linux/slab.h>
> +#include <linux/of_i2c.h>

This line breaks the build on the x86 platform, so I'm going to drop
this whole patch, sorry.

Please fix it up so that it builds properly and resend.

thanks,

greg k-h
Daniel Sangorrin Jan. 6, 2014, 2:33 a.m. UTC | #2
On 2014/01/06 7:05, Greg KH wrote:
> On Tue, Dec 24, 2013 at 03:15:01PM +0900, Daniel Sangorrin wrote:
>> From: Rob Armstrong <ra@xilinx.com>
>>
>> This merges support for the si5790 clock generator from the Xilinx
>> repository (commit efc27505715e64526653f35274717c0fc56491e3 from
>> master branch).
>>
>> Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp>
>> Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp>
>> ---
>>  drivers/misc/Kconfig      |  10 +
>>  drivers/misc/Makefile     |   1 +
>>  drivers/misc/si570.c      | 576 ++++++++++++++++++++++++++++++++++++++++++++++
>>  include/linux/i2c/si570.h |  31 +++
>>  4 files changed, 618 insertions(+)
>>  create mode 100644 drivers/misc/si570.c
>>  create mode 100644 include/linux/i2c/si570.h
>>
>> diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
>> index c002d86..1c9fd72 100644
>> --- a/drivers/misc/Kconfig
>> +++ b/drivers/misc/Kconfig
>> @@ -507,6 +507,16 @@ config USB_SWITCH_FSA9480
>>  	  stereo and mono audio, video, microphone and UART data to use
>>  	  a common connector port.
>>  
>> +config SI570
>> +	tristate "Silicon Labs Si570 Clock Generator"
>> +	depends on I2C && SYSFS
>> +	help
>> +	  If you say yes here you get support for the Silicon Labs Si570
>> +	  digital clock generator.
>> +
>> +	  To compile this driver as a module, choose M here: the module
>> +	  will be called si570
>> +
>>  config LATTICE_ECP3_CONFIG
>>  	tristate "Lattice ECP3 FPGA bitstream configuration via SPI"
>>  	depends on SPI && SYSFS
>> diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
>> index c235d5b..e84bcaa 100644
>> --- a/drivers/misc/Makefile
>> +++ b/drivers/misc/Makefile
>> @@ -50,6 +50,7 @@ obj-y				+= carma/
>>  obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o
>>  obj-$(CONFIG_ALTERA_STAPL)	+=altera-stapl/
>>  obj-$(CONFIG_INTEL_MEI)		+= mei/
>> +obj-$(CONFIG_SI570)		+= si570.o
>>  obj-$(CONFIG_VMWARE_VMCI)	+= vmw_vmci/
>>  obj-$(CONFIG_LATTICE_ECP3_CONFIG)	+= lattice-ecp3-config.o
>>  obj-$(CONFIG_SRAM)		+= sram.o
>> diff --git a/drivers/misc/si570.c b/drivers/misc/si570.c
>> new file mode 100644
>> index 0000000..30d8288
>> --- /dev/null
>> +++ b/drivers/misc/si570.c
>> @@ -0,0 +1,576 @@
>> +/*
>> + * Driver for Silicon Labs Si570/Si571 Programmable XO/VCXO
>> + *
>> + * Copyright (C) 2010, 2011 Ericsson AB.
>> + * Copyright (C) 2011 Guenter Roeck.
>> + *
>> + * Author: Guenter Roeck <guenter.roeck@ericsson.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that 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.
>> + */
>> +
>> +#include <linux/module.h>
>> +#include <linux/jiffies.h>
>> +#include <linux/i2c.h>
>> +#include <linux/err.h>
>> +#include <linux/mutex.h>
>> +#include <linux/delay.h>
>> +#include <linux/log2.h>
>> +#include <linux/slab.h>
>> +#include <linux/of_i2c.h>
> 
> This line breaks the build on the x86 platform, so I'm going to drop
> this whole patch, sorry.
> 
> Please fix it up so that it builds properly and resend.

Hi Greg,

I just tested the x86 build with "make allyesconfig" and
"make i386_defconfig" (with SI570 enabled) and both of them
ended without problems on my machine.

Could it be a collision against patches sent by other people?

Best regards
Daniel
Greg KH Jan. 6, 2014, 3:29 a.m. UTC | #3
On Mon, Jan 06, 2014 at 11:33:00AM +0900, Daniel Sangorrin wrote:
> 
> 
> On 2014/01/06 7:05, Greg KH wrote:
> > On Tue, Dec 24, 2013 at 03:15:01PM +0900, Daniel Sangorrin wrote:
> >> From: Rob Armstrong <ra@xilinx.com>
> >>
> >> This merges support for the si5790 clock generator from the Xilinx
> >> repository (commit efc27505715e64526653f35274717c0fc56491e3 from
> >> master branch).
> >>
> >> Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp>
> >> Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp>
> >> ---
> >>  drivers/misc/Kconfig      |  10 +
> >>  drivers/misc/Makefile     |   1 +
> >>  drivers/misc/si570.c      | 576 ++++++++++++++++++++++++++++++++++++++++++++++
> >>  include/linux/i2c/si570.h |  31 +++
> >>  4 files changed, 618 insertions(+)
> >>  create mode 100644 drivers/misc/si570.c
> >>  create mode 100644 include/linux/i2c/si570.h
> >>
> >> diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
> >> index c002d86..1c9fd72 100644
> >> --- a/drivers/misc/Kconfig
> >> +++ b/drivers/misc/Kconfig
> >> @@ -507,6 +507,16 @@ config USB_SWITCH_FSA9480
> >>  	  stereo and mono audio, video, microphone and UART data to use
> >>  	  a common connector port.
> >>  
> >> +config SI570
> >> +	tristate "Silicon Labs Si570 Clock Generator"
> >> +	depends on I2C && SYSFS
> >> +	help
> >> +	  If you say yes here you get support for the Silicon Labs Si570
> >> +	  digital clock generator.
> >> +
> >> +	  To compile this driver as a module, choose M here: the module
> >> +	  will be called si570
> >> +
> >>  config LATTICE_ECP3_CONFIG
> >>  	tristate "Lattice ECP3 FPGA bitstream configuration via SPI"
> >>  	depends on SPI && SYSFS
> >> diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
> >> index c235d5b..e84bcaa 100644
> >> --- a/drivers/misc/Makefile
> >> +++ b/drivers/misc/Makefile
> >> @@ -50,6 +50,7 @@ obj-y				+= carma/
> >>  obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o
> >>  obj-$(CONFIG_ALTERA_STAPL)	+=altera-stapl/
> >>  obj-$(CONFIG_INTEL_MEI)		+= mei/
> >> +obj-$(CONFIG_SI570)		+= si570.o
> >>  obj-$(CONFIG_VMWARE_VMCI)	+= vmw_vmci/
> >>  obj-$(CONFIG_LATTICE_ECP3_CONFIG)	+= lattice-ecp3-config.o
> >>  obj-$(CONFIG_SRAM)		+= sram.o
> >> diff --git a/drivers/misc/si570.c b/drivers/misc/si570.c
> >> new file mode 100644
> >> index 0000000..30d8288
> >> --- /dev/null
> >> +++ b/drivers/misc/si570.c
> >> @@ -0,0 +1,576 @@
> >> +/*
> >> + * Driver for Silicon Labs Si570/Si571 Programmable XO/VCXO
> >> + *
> >> + * Copyright (C) 2010, 2011 Ericsson AB.
> >> + * Copyright (C) 2011 Guenter Roeck.
> >> + *
> >> + * Author: Guenter Roeck <guenter.roeck@ericsson.com>
> >> + *
> >> + * This program is free software; you can redistribute it and/or modify
> >> + * it under the terms of the GNU General Public License as published by
> >> + * the Free Software Foundation; either version 2 of the License, or
> >> + * (at your option) any later version.
> >> + *
> >> + * This program is distributed in the hope that 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.
> >> + */
> >> +
> >> +#include <linux/module.h>
> >> +#include <linux/jiffies.h>
> >> +#include <linux/i2c.h>
> >> +#include <linux/err.h>
> >> +#include <linux/mutex.h>
> >> +#include <linux/delay.h>
> >> +#include <linux/log2.h>
> >> +#include <linux/slab.h>
> >> +#include <linux/of_i2c.h>
> > 
> > This line breaks the build on the x86 platform, so I'm going to drop
> > this whole patch, sorry.
> > 
> > Please fix it up so that it builds properly and resend.
> 
> Hi Greg,
> 
> I just tested the x86 build with "make allyesconfig" and
> "make i386_defconfig" (with SI570 enabled) and both of them
> ended without problems on my machine.
> 
> Could it be a collision against patches sent by other people?

Ah, yes, it is due to patch 687b81d083c082bc1e853032e3a2a54f8c251d27
(from Linus's tree) in the LTSI tree now.  You'll have to handle this
when making this code work properly upstream, so might as well make the
change now :)

thanks,

greg k-h
Daniel Sangorrin Jan. 6, 2014, 8:09 a.m. UTC | #4
On 2014/01/06 12:29, Greg KH wrote:
> On Mon, Jan 06, 2014 at 11:33:00AM +0900, Daniel Sangorrin wrote:
>>
>>
>> On 2014/01/06 7:05, Greg KH wrote:
>>> On Tue, Dec 24, 2013 at 03:15:01PM +0900, Daniel Sangorrin wrote:
>>>> From: Rob Armstrong <ra@xilinx.com>
>>>>
>>>> This merges support for the si5790 clock generator from the Xilinx
>>>> repository (commit efc27505715e64526653f35274717c0fc56491e3 from
>>>> master branch).
>>>>
>>>> Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp>
>>>> Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp>
>>>> ---
>>>>  drivers/misc/Kconfig      |  10 +
>>>>  drivers/misc/Makefile     |   1 +
>>>>  drivers/misc/si570.c      | 576 ++++++++++++++++++++++++++++++++++++++++++++++
>>>>  include/linux/i2c/si570.h |  31 +++
>>>>  4 files changed, 618 insertions(+)
>>>>  create mode 100644 drivers/misc/si570.c
>>>>  create mode 100644 include/linux/i2c/si570.h
>>>>
>>>> diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
>>>> index c002d86..1c9fd72 100644
>>>> --- a/drivers/misc/Kconfig
>>>> +++ b/drivers/misc/Kconfig
>>>> @@ -507,6 +507,16 @@ config USB_SWITCH_FSA9480
>>>>  	  stereo and mono audio, video, microphone and UART data to use
>>>>  	  a common connector port.
>>>>  
>>>> +config SI570
>>>> +	tristate "Silicon Labs Si570 Clock Generator"
>>>> +	depends on I2C && SYSFS
>>>> +	help
>>>> +	  If you say yes here you get support for the Silicon Labs Si570
>>>> +	  digital clock generator.
>>>> +
>>>> +	  To compile this driver as a module, choose M here: the module
>>>> +	  will be called si570
>>>> +
>>>>  config LATTICE_ECP3_CONFIG
>>>>  	tristate "Lattice ECP3 FPGA bitstream configuration via SPI"
>>>>  	depends on SPI && SYSFS
>>>> diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
>>>> index c235d5b..e84bcaa 100644
>>>> --- a/drivers/misc/Makefile
>>>> +++ b/drivers/misc/Makefile
>>>> @@ -50,6 +50,7 @@ obj-y				+= carma/
>>>>  obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o
>>>>  obj-$(CONFIG_ALTERA_STAPL)	+=altera-stapl/
>>>>  obj-$(CONFIG_INTEL_MEI)		+= mei/
>>>> +obj-$(CONFIG_SI570)		+= si570.o
>>>>  obj-$(CONFIG_VMWARE_VMCI)	+= vmw_vmci/
>>>>  obj-$(CONFIG_LATTICE_ECP3_CONFIG)	+= lattice-ecp3-config.o
>>>>  obj-$(CONFIG_SRAM)		+= sram.o
>>>> diff --git a/drivers/misc/si570.c b/drivers/misc/si570.c
>>>> new file mode 100644
>>>> index 0000000..30d8288
>>>> --- /dev/null
>>>> +++ b/drivers/misc/si570.c
>>>> @@ -0,0 +1,576 @@
>>>> +/*
>>>> + * Driver for Silicon Labs Si570/Si571 Programmable XO/VCXO
>>>> + *
>>>> + * Copyright (C) 2010, 2011 Ericsson AB.
>>>> + * Copyright (C) 2011 Guenter Roeck.
>>>> + *
>>>> + * Author: Guenter Roeck <guenter.roeck@ericsson.com>
>>>> + *
>>>> + * This program is free software; you can redistribute it and/or modify
>>>> + * it under the terms of the GNU General Public License as published by
>>>> + * the Free Software Foundation; either version 2 of the License, or
>>>> + * (at your option) any later version.
>>>> + *
>>>> + * This program is distributed in the hope that 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.
>>>> + */
>>>> +
>>>> +#include <linux/module.h>
>>>> +#include <linux/jiffies.h>
>>>> +#include <linux/i2c.h>
>>>> +#include <linux/err.h>
>>>> +#include <linux/mutex.h>
>>>> +#include <linux/delay.h>
>>>> +#include <linux/log2.h>
>>>> +#include <linux/slab.h>
>>>> +#include <linux/of_i2c.h>
>>>
>>> This line breaks the build on the x86 platform, so I'm going to drop
>>> this whole patch, sorry.
>>>
>>> Please fix it up so that it builds properly and resend.
>>
>> Hi Greg,
>>
>> I just tested the x86 build with "make allyesconfig" and
>> "make i386_defconfig" (with SI570 enabled) and both of them
>> ended without problems on my machine.
>>
>> Could it be a collision against patches sent by other people?
> 
> Ah, yes, it is due to patch 687b81d083c082bc1e853032e3a2a54f8c251d27
> (from Linus's tree) in the LTSI tree now.  You'll have to handle this
> when making this code work properly upstream, so might as well make the
> change now :)
> 
> thanks,
> 
> greg k-h
> 
> 
Hi Greg,

I applied the LTSI patches on Linux 3.10.25 with quilt.

Note: I noticed that I had to repeat the commands
'quilt push -a -f' and 'quilt refresh' several
times because quilt was complaining (is that normal?).

After applying all of the patches, and adding the
si570 patch as well, I managed to reproduce the problem with
the x86 build that you mentioned.

I just had to remove that line (#include <linux/of_i2c.h>)
to fix the x86 build.

Unfortunately, I noticed that all ARM builds are in fact
broken with the current LTSI patches. This is the error message
that appears when I try to build an ARM kernel:

  CC      arch/arm/kernel/setup.o
arch/arm/kernel/setup.c: In function 'customize_machine':
arch/arm/kernel/setup.c:686: error: implicit declaration of function 'of_platform_populate'
arch/arm/kernel/setup.c:686: error: 'of_default_bus_match_table' undeclared (first use in this function)
arch/arm/kernel/setup.c:686: error: (Each undeclared identifier is reported only once
arch/arm/kernel/setup.c:686: error: for each function it appears in.)
make[1]: *** [arch/arm/kernel/setup.o] Error 1
make: *** [arch/arm/kernel] Error 2

After some research, I managed to track this down to the
following patch:

#patches.baytrail/1134-of-remove-CONFIG_OF_DEVICE.patch

If I ommit that patch, I can build the Zynq kernel (and
also other ARM board kernels which had the same problem)
without problems. Unfortunately there are two problems
with that too:

  1.- The Zynq kernel mostly works but it seems
      that I2C devices (eeprom, rtc) are not recognized
      anymore.
  2.- 'make allyesconfig' fails again (probably some conflict
      with other patches)

Do you have any suggestion of how to fix this?

Best regards
Daniel
Greg KH Jan. 7, 2014, 2:43 a.m. UTC | #5
On Mon, Jan 06, 2014 at 05:09:05PM +0900, Daniel Sangorrin wrote:
> I applied the LTSI patches on Linux 3.10.25 with quilt.
> 
> Note: I noticed that I had to repeat the commands
> 'quilt push -a -f' and 'quilt refresh' several
> times because quilt was complaining (is that normal?).

No, that's not normal at all, it shouldn't happen.  What patches gave
you problems?

> After applying all of the patches, and adding the
> si570 patch as well, I managed to reproduce the problem with
> the x86 build that you mentioned.
> 
> I just had to remove that line (#include <linux/of_i2c.h>)
> to fix the x86 build.
> 
> Unfortunately, I noticed that all ARM builds are in fact
> broken with the current LTSI patches. This is the error message
> that appears when I try to build an ARM kernel:
> 
>   CC      arch/arm/kernel/setup.o
> arch/arm/kernel/setup.c: In function 'customize_machine':
> arch/arm/kernel/setup.c:686: error: implicit declaration of function 'of_platform_populate'
> arch/arm/kernel/setup.c:686: error: 'of_default_bus_match_table' undeclared (first use in this function)
> arch/arm/kernel/setup.c:686: error: (Each undeclared identifier is reported only once
> arch/arm/kernel/setup.c:686: error: for each function it appears in.)
> make[1]: *** [arch/arm/kernel/setup.o] Error 1
> make: *** [arch/arm/kernel] Error 2
> 
> After some research, I managed to track this down to the
> following patch:
> 
> #patches.baytrail/1134-of-remove-CONFIG_OF_DEVICE.patch
> 
> If I ommit that patch, I can build the Zynq kernel (and
> also other ARM board kernels which had the same problem)
> without problems. Unfortunately there are two problems
> with that too:
> 
>   1.- The Zynq kernel mostly works but it seems
>       that I2C devices (eeprom, rtc) are not recognized
>       anymore.

As these OF patches are upstream, do you also have this problem with
your patches on 3.12?

>   2.- 'make allyesconfig' fails again (probably some conflict
>       with other patches)

What is the error you get with the build?

thanks,

greg k-h
Daniel Sangorrin Jan. 7, 2014, 5:58 a.m. UTC | #6
On 2014/01/07 11:43, Greg KH wrote:
> On Mon, Jan 06, 2014 at 05:09:05PM +0900, Daniel Sangorrin wrote:
>> I applied the LTSI patches on Linux 3.10.25 with quilt.
>>
>> Note: I noticed that I had to repeat the commands
>> 'quilt push -a -f' and 'quilt refresh' several
>> times because quilt was complaining (is that normal?).
> 
> No, that's not normal at all, it shouldn't happen.  What patches gave
> you problems?

This is the list of patches that needed refresh:

modified:   patches.baytrail/1140-dmaengine-dw-select-DW_DMAC_BIG_ENDIAN_IO-automagica.patch
modified:   patches.baytrail/1178-dma-dw-improve-comparison-with-0.patch
modified:   patches.baytrail/1179-dma-dw-allow-shared-interrupts.patch
modified:   patches.baytrail/1180-dma-dw-return-DMA_SUCCESS-immediately-from-device_tx.patch
modified:   patches.baytrail/1181-dma-dw-return-DMA_PAUSED-only-if-cookie-status-is-DM.patch
modified:   patches.renesas/0020-drm-rcar-du-Rename-platform-data-fields-to-match-wha.patch
modified:   patches.renesas/0031-drm-rcar-du-Rework-output-routing-support.patch
modified:   patches.renesas/0033-drm-rcar-du-Add-internal-LVDS-encoder-support.patch
modified:   patches.renesas/0056-DMA-shdma-remove-private-and-unused-defines-from-a-g.patch
modified:   patches.renesas/0058-DMA-shdma-add-r8a73a4-DMAC-data-to-the-device-ID-tab.patch

The typical error messages were something like:

can't find file to patch at input line 22
Perhaps you used the wrong -p or --strip option?
...
Skip this patch? [y]
Skipping patch.
2 out of 2 hunks ignored

>> After applying all of the patches, and adding the
>> si570 patch as well, I managed to reproduce the problem with
>> the x86 build that you mentioned.
>>
>> I just had to remove that line (#include <linux/of_i2c.h>)
>> to fix the x86 build.
>>
>> Unfortunately, I noticed that all ARM builds are in fact
>> broken with the current LTSI patches. This is the error message
>> that appears when I try to build an ARM kernel:
>>
>>   CC      arch/arm/kernel/setup.o
>> arch/arm/kernel/setup.c: In function 'customize_machine':
>> arch/arm/kernel/setup.c:686: error: implicit declaration of function 'of_platform_populate'
>> arch/arm/kernel/setup.c:686: error: 'of_default_bus_match_table' undeclared (first use in this function)
>> arch/arm/kernel/setup.c:686: error: (Each undeclared identifier is reported only once
>> arch/arm/kernel/setup.c:686: error: for each function it appears in.)
>> make[1]: *** [arch/arm/kernel/setup.o] Error 1
>> make: *** [arch/arm/kernel] Error 2
>>
>> After some research, I managed to track this down to the
>> following patch:
>>
>> #patches.baytrail/1134-of-remove-CONFIG_OF_DEVICE.patch
>>
>> If I ommit that patch, I can build the Zynq kernel (and
>> also other ARM board kernels which had the same problem)
>> without problems. Unfortunately there are two problems
>> with that too:
>>
>>   1.- The Zynq kernel mostly works but it seems
>>       that I2C devices (eeprom, rtc) are not recognized
>>       anymore.
> 
> As these OF patches are upstream, do you also have this problem with
> your patches on 3.12?

First, the ARM build problems can be fixed with:

$ git cherry-pick 8a46f4f  (I will send you a signed patch in a minute)

About the I2C devices on 3.12, I haven't tried that yet because I could not
run successfully the mainline kernel on the Zynq board. I think the
reason is that the device tree in mainline is not a complete one. I will try
to make it working though.

> 
>>   2.- 'make allyesconfig' fails again (probably some conflict
>>       with other patches)
> 
> What is the error you get with the build?
> 

With the cherry-pick above, that problem should be gone. But I will
test it again just in case, after I make the I2C drivers work.

> thanks,
> 
> greg k-h
> 
> 

Thanks,
Daniel
Daniel Sangorrin Jan. 7, 2014, 9:55 a.m. UTC | #7
On 2014/01/07 14:58, Daniel Sangorrin wrote:
> 
> On 2014/01/07 11:43, Greg KH wrote:
>> On Mon, Jan 06, 2014 at 05:09:05PM +0900, Daniel Sangorrin wrote:
>>> I applied the LTSI patches on Linux 3.10.25 with quilt.
>>>
>>> Note: I noticed that I had to repeat the commands
>>> 'quilt push -a -f' and 'quilt refresh' several
>>> times because quilt was complaining (is that normal?).
>>
>> No, that's not normal at all, it shouldn't happen.  What patches gave
>> you problems?
> 
> This is the list of patches that needed refresh:
> 
> modified:   patches.baytrail/1140-dmaengine-dw-select-DW_DMAC_BIG_ENDIAN_IO-automagica.patch
> modified:   patches.baytrail/1178-dma-dw-improve-comparison-with-0.patch
> modified:   patches.baytrail/1179-dma-dw-allow-shared-interrupts.patch
> modified:   patches.baytrail/1180-dma-dw-return-DMA_SUCCESS-immediately-from-device_tx.patch
> modified:   patches.baytrail/1181-dma-dw-return-DMA_PAUSED-only-if-cookie-status-is-DM.patch
> modified:   patches.renesas/0020-drm-rcar-du-Rename-platform-data-fields-to-match-wha.patch
> modified:   patches.renesas/0031-drm-rcar-du-Rework-output-routing-support.patch
> modified:   patches.renesas/0033-drm-rcar-du-Add-internal-LVDS-encoder-support.patch
> modified:   patches.renesas/0056-DMA-shdma-remove-private-and-unused-defines-from-a-g.patch
> modified:   patches.renesas/0058-DMA-shdma-add-r8a73a4-DMAC-data-to-the-device-ID-tab.patch
> 
> The typical error messages were something like:
> 
> can't find file to patch at input line 22
> Perhaps you used the wrong -p or --strip option?
> ...
> Skip this patch? [y]
> Skipping patch.
> 2 out of 2 hunks ignored
> 
>>> After applying all of the patches, and adding the
>>> si570 patch as well, I managed to reproduce the problem with
>>> the x86 build that you mentioned.
>>>
>>> I just had to remove that line (#include <linux/of_i2c.h>)
>>> to fix the x86 build.
>>>
>>> Unfortunately, I noticed that all ARM builds are in fact
>>> broken with the current LTSI patches. This is the error message
>>> that appears when I try to build an ARM kernel:
>>>
>>>   CC      arch/arm/kernel/setup.o
>>> arch/arm/kernel/setup.c: In function 'customize_machine':
>>> arch/arm/kernel/setup.c:686: error: implicit declaration of function 'of_platform_populate'
>>> arch/arm/kernel/setup.c:686: error: 'of_default_bus_match_table' undeclared (first use in this function)
>>> arch/arm/kernel/setup.c:686: error: (Each undeclared identifier is reported only once
>>> arch/arm/kernel/setup.c:686: error: for each function it appears in.)
>>> make[1]: *** [arch/arm/kernel/setup.o] Error 1
>>> make: *** [arch/arm/kernel] Error 2
>>>
>>> After some research, I managed to track this down to the
>>> following patch:
>>>
>>> #patches.baytrail/1134-of-remove-CONFIG_OF_DEVICE.patch
>>>
>>> If I ommit that patch, I can build the Zynq kernel (and
>>> also other ARM board kernels which had the same problem)
>>> without problems. Unfortunately there are two problems
>>> with that too:
>>>
>>>   1.- The Zynq kernel mostly works but it seems
>>>       that I2C devices (eeprom, rtc) are not recognized
>>>       anymore.
>>
>> As these OF patches are upstream, do you also have this problem with
>> your patches on 3.12?
> 
> First, the ARM build problems can be fixed with:
> 
> $ git cherry-pick 8a46f4f  (I will send you a signed patch in a minute)
> 
> About the I2C devices on 3.12, I haven't tried that yet because I could not
> run successfully the mainline kernel on the Zynq board. I think the
> reason is that the device tree in mainline is not a complete one. I will try
> to make it working though.

Ok, I found the problem!

There was a "silent" collision of with the following patch that caused
part of the Xilinx I2C driver not be included in the build:

patches.baytrail/1125-i2c-vt8500-Add-support-for-I2C-bus-on-Wondermedia-So.patch

I will send the fix tomorrow (just a few lines) as a patch if you don't mind.

Best regards,
Daniel
Daniel Sangorrin Jan. 8, 2014, 1:57 a.m. UTC | #8
On 2014/01/07 18:55, Daniel Sangorrin wrote:
> On 2014/01/07 14:58, Daniel Sangorrin wrote:
>>
>> On 2014/01/07 11:43, Greg KH wrote:
>>> On Mon, Jan 06, 2014 at 05:09:05PM +0900, Daniel Sangorrin wrote:
>>>> I applied the LTSI patches on Linux 3.10.25 with quilt.
>>>>
>>>> Note: I noticed that I had to repeat the commands
>>>> 'quilt push -a -f' and 'quilt refresh' several
>>>> times because quilt was complaining (is that normal?).
>>>
>>> No, that's not normal at all, it shouldn't happen.  What patches gave
>>> you problems?
>>
>> This is the list of patches that needed refresh:
>>
>> modified:   patches.baytrail/1140-dmaengine-dw-select-DW_DMAC_BIG_ENDIAN_IO-automagica.patch
>> modified:   patches.baytrail/1178-dma-dw-improve-comparison-with-0.patch
>> modified:   patches.baytrail/1179-dma-dw-allow-shared-interrupts.patch
>> modified:   patches.baytrail/1180-dma-dw-return-DMA_SUCCESS-immediately-from-device_tx.patch
>> modified:   patches.baytrail/1181-dma-dw-return-DMA_PAUSED-only-if-cookie-status-is-DM.patch
>> modified:   patches.renesas/0020-drm-rcar-du-Rename-platform-data-fields-to-match-wha.patch
>> modified:   patches.renesas/0031-drm-rcar-du-Rework-output-routing-support.patch
>> modified:   patches.renesas/0033-drm-rcar-du-Add-internal-LVDS-encoder-support.patch
>> modified:   patches.renesas/0056-DMA-shdma-remove-private-and-unused-defines-from-a-g.patch
>> modified:   patches.renesas/0058-DMA-shdma-add-r8a73a4-DMAC-data-to-the-device-ID-tab.patch
>>
>> The typical error messages were something like:
>>
>> can't find file to patch at input line 22
>> Perhaps you used the wrong -p or --strip option?
>> ...
>> Skip this patch? [y]
>> Skipping patch.
>> 2 out of 2 hunks ignored

Greg,

Sorry, I didn't notice that in the LTSI README the minimum 'patch' version
was written. It seems that I was using an old one.

After updating it to version 1.7 those problems did not appear anymore.

Regards,
Daniel
diff mbox

Patch

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index c002d86..1c9fd72 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -507,6 +507,16 @@  config USB_SWITCH_FSA9480
 	  stereo and mono audio, video, microphone and UART data to use
 	  a common connector port.
 
+config SI570
+	tristate "Silicon Labs Si570 Clock Generator"
+	depends on I2C && SYSFS
+	help
+	  If you say yes here you get support for the Silicon Labs Si570
+	  digital clock generator.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called si570
+
 config LATTICE_ECP3_CONFIG
 	tristate "Lattice ECP3 FPGA bitstream configuration via SPI"
 	depends on SPI && SYSFS
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index c235d5b..e84bcaa 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -50,6 +50,7 @@  obj-y				+= carma/
 obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o
 obj-$(CONFIG_ALTERA_STAPL)	+=altera-stapl/
 obj-$(CONFIG_INTEL_MEI)		+= mei/
+obj-$(CONFIG_SI570)		+= si570.o
 obj-$(CONFIG_VMWARE_VMCI)	+= vmw_vmci/
 obj-$(CONFIG_LATTICE_ECP3_CONFIG)	+= lattice-ecp3-config.o
 obj-$(CONFIG_SRAM)		+= sram.o
diff --git a/drivers/misc/si570.c b/drivers/misc/si570.c
new file mode 100644
index 0000000..30d8288
--- /dev/null
+++ b/drivers/misc/si570.c
@@ -0,0 +1,576 @@ 
+/*
+ * Driver for Silicon Labs Si570/Si571 Programmable XO/VCXO
+ *
+ * Copyright (C) 2010, 2011 Ericsson AB.
+ * Copyright (C) 2011 Guenter Roeck.
+ *
+ * Author: Guenter Roeck <guenter.roeck@ericsson.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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.
+ */
+
+#include <linux/module.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/log2.h>
+#include <linux/slab.h>
+#include <linux/of_i2c.h>
+#include <linux/i2c/si570.h>
+
+/* Si570 registers */
+#define SI570_REG_HS_N1		7
+#define SI570_REG_N1_RFREQ0	8
+#define SI570_REG_RFREQ1	9
+#define SI570_REG_RFREQ2	10
+#define SI570_REG_RFREQ3	11
+#define SI570_REG_RFREQ4	12
+#define SI570_REG_CONTROL	135
+#define SI570_REG_FREEZE_DCO	137
+
+#define HS_DIV_SHIFT		5
+#define HS_DIV_MASK		0xe0
+#define HS_DIV_OFFSET		4
+#define N1_6_2_MASK		0x1f
+#define N1_1_0_MASK		0xc0
+#define RFREQ_37_32_MASK	0x3f
+
+#define SI570_FOUT_FACTORY_DFLT	156250000LL
+#define SI598_FOUT_FACTORY_DFLT	10000000LL
+
+#define SI570_MIN_FREQ		10000000L
+#define SI570_MAX_FREQ		1417500000L
+#define SI598_MAX_FREQ		525000000L
+
+#define FDCO_MIN		4850000000LL
+#define FDCO_MAX		5670000000LL
+#define FDCO_CENTER		((FDCO_MIN + FDCO_MAX) / 2)
+
+#define SI570_CNTRL_RECALL	(1 << 0)
+#define SI570_CNTRL_FREEZE_ADC	(1 << 4)
+#define SI570_CNTRL_FREEZE_M	(1 << 5)
+#define SI570_CNTRL_NEWFREQ	(1 << 6)
+#define SI570_CNTRL_RESET	(1 << 7)
+
+#define SI570_FREEZE_DCO	(1 << 4)
+#define SI570_UNFREEZE_DCO	0xEF
+
+struct si570_data {
+	struct attribute_group attrs;
+	struct mutex lock;
+	u64 max_freq;
+	u64 fout;		/* Factory default frequency */
+	u64 fxtal;		/* Factory xtal frequency */
+	unsigned int n1;
+	unsigned int hs_div;
+	u64 rfreq;
+	u64 frequency;
+};
+
+
+static struct i2c_client *si570_client;
+
+
+static int si570_get_defaults(struct i2c_client *client)
+{
+	struct si570_data *data = i2c_get_clientdata(client);
+	int reg1, reg2, reg3, reg4, reg5, reg6;
+	u64 fdco;
+
+	i2c_smbus_write_byte_data(client, SI570_REG_CONTROL,
+				  SI570_CNTRL_RECALL);
+
+	reg1 = i2c_smbus_read_byte_data(client, SI570_REG_HS_N1);
+	if (reg1 < 0)
+		return reg1;
+	reg2 = i2c_smbus_read_byte_data(client, SI570_REG_N1_RFREQ0);
+	if (reg2 < 0)
+		return reg2;
+	reg3 = i2c_smbus_read_byte_data(client, SI570_REG_RFREQ1);
+	if (reg3 < 0)
+		return reg3;
+	reg4 = i2c_smbus_read_byte_data(client, SI570_REG_RFREQ2);
+	if (reg4 < 0)
+		return reg4;
+	reg5 = i2c_smbus_read_byte_data(client, SI570_REG_RFREQ3);
+	if (reg5 < 0)
+		return reg5;
+	reg6 = i2c_smbus_read_byte_data(client, SI570_REG_RFREQ4);
+	if (reg6 < 0)
+		return reg6;
+
+	data->hs_div = ((reg1 & HS_DIV_MASK) >> HS_DIV_SHIFT) + HS_DIV_OFFSET;
+	data->n1 = ((reg1 & N1_6_2_MASK) << 2) + ((reg2 & N1_1_0_MASK) >> 6)
+	  + 1;
+	/* Handle invalid cases */
+	if (data->n1 > 1)
+		data->n1 &= ~1;
+
+	data->rfreq = reg2 & RFREQ_37_32_MASK;
+	data->rfreq = (data->rfreq << 8) + reg3;
+	data->rfreq = (data->rfreq << 8) + reg4;
+	data->rfreq = (data->rfreq << 8) + reg5;
+	data->rfreq = (data->rfreq << 8) + reg6;
+
+	/*
+	 * Accept optional precision loss to avoid arithmetic overflows.
+	 * Acceptable per Silicon Labs Application Note AN334.
+	 */
+	fdco = data->fout * data->n1 * data->hs_div;
+	if (fdco >= (1LL << 36))
+		data->fxtal = div64_u64((fdco << 24), (data->rfreq >> 4));
+	else
+		data->fxtal = div64_u64((fdco << 28), data->rfreq);
+
+	data->frequency = data->fout;
+
+	return 0;
+}
+
+/*
+ * Update rfreq registers
+ * This function must be called with update mutex lock held.
+ */
+static void si570_update_rfreq(struct i2c_client *client,
+			       struct si570_data *data)
+{
+	int status;
+	status = i2c_smbus_write_byte_data(client, SI570_REG_N1_RFREQ0,
+				  ((data->n1 - 1) << 6)
+				  | ((data->rfreq >> 32) & RFREQ_37_32_MASK));
+	if (status < 0)
+		dev_err(&client->dev,
+			"unable to write 0x%llX to REG_N1_RFREQ0: %d\n",
+			(((data->n1 - 1) << 6) | ((data->rfreq >> 32) &
+			RFREQ_37_32_MASK)) & 0xff, status);
+	status = i2c_smbus_write_byte_data(client, SI570_REG_RFREQ1,
+				  (data->rfreq >> 24) & 0xff);
+	if (status < 0)
+		dev_err(&client->dev,
+			"unable to write 0x%llX to REG_RFREQ1: %d\n",
+			(data->rfreq >> 24) & 0xff, status);
+	status = i2c_smbus_write_byte_data(client, SI570_REG_RFREQ2,
+				  (data->rfreq >> 16) & 0xff);
+	if (status < 0)
+		dev_err(&client->dev,
+			"unable to write 0x%llX to REG_RFREQ2: %d\n",
+			(data->rfreq >> 16) & 0xff, status);
+	status = i2c_smbus_write_byte_data(client, SI570_REG_RFREQ3,
+				  (data->rfreq >> 8) & 0xff);
+	if (status < 0)
+		dev_err(&client->dev,
+			"unable to write 0x%llX to REG_RFREQ3: %d\n",
+			(data->rfreq >> 8) & 0xff, status);
+	status = i2c_smbus_write_byte_data(client, SI570_REG_RFREQ4,
+				  data->rfreq & 0xff);
+	if (status < 0)
+		dev_err(&client->dev,
+			"unable to write 0x%llX to REG_RFREQ4: %d\n",
+			data->rfreq & 0xff, status);
+}
+
+/*
+ * Update si570 frequency for small frequency changes (< 3,500 ppm)
+ * This function must be called with update mutex lock held.
+ */
+static int si570_set_frequency_small(struct i2c_client *client,
+				     struct si570_data *data,
+				     unsigned long frequency)
+{
+	data->frequency = frequency;
+	/* This is a re-implementation of DIV_ROUND_CLOSEST
+	 * using the div64_u64 function lieu of letting the compiler
+	 * insert EABI calls
+	 */
+	data->rfreq = div64_u64((data->rfreq * frequency) +
+		div64_u64(data->frequency, 2), data->frequency);
+	i2c_smbus_write_byte_data(client, SI570_REG_CONTROL,
+				  SI570_CNTRL_FREEZE_M);
+	si570_update_rfreq(client, data);
+	i2c_smbus_write_byte_data(client, SI570_REG_CONTROL, 0);
+
+	return 0;
+}
+
+static const uint8_t si570_hs_div_values[] = { 11, 9, 7, 6, 5, 4 };
+
+/*
+ * Set si570 frequency.
+ * This function must be called with update mutex lock held.
+ */
+static int si570_set_frequency(struct i2c_client *client,
+			       struct si570_data *data,
+			       unsigned long frequency)
+{
+	int i, n1, hs_div;
+	u64 fdco, best_fdco = ULLONG_MAX;
+
+	for (i = 0; i < ARRAY_SIZE(si570_hs_div_values); i++) {
+		hs_div = si570_hs_div_values[i];
+		/* Calculate lowest possible value for n1 */
+		n1 = div64_u64(div64_u64(FDCO_MIN, (u64)hs_div),
+			(u64)frequency);
+		if (!n1 || (n1 & 1))
+			n1++;
+		while (n1 <= 128) {
+			fdco = (u64)frequency * (u64)hs_div * (u64)n1;
+			if (fdco > FDCO_MAX)
+				break;
+			if (fdco >= FDCO_MIN && fdco < best_fdco) {
+				data->n1 = n1;
+				data->hs_div = hs_div;
+				data->frequency = frequency;
+				data->rfreq = div64_u64((fdco << 28),
+					data->fxtal);
+				best_fdco = fdco;
+			}
+			n1 += (n1 == 1 ? 1 : 2);
+		}
+	}
+	if (best_fdco == ULLONG_MAX) {
+		dev_err(&client->dev, "error - best FDCO is out of range\n");
+		return -EINVAL;
+	}
+
+	/* The DCO reg should be accessed with a read-modify-write operation
+	 * per AN334
+	 */
+	i2c_smbus_write_byte_data(client, SI570_REG_FREEZE_DCO,
+				  SI570_FREEZE_DCO);
+	i2c_smbus_write_byte_data(client, SI570_REG_HS_N1,
+				  ((data->hs_div - HS_DIV_OFFSET) <<
+				   HS_DIV_SHIFT)
+				  | (((data->n1 - 1) >> 2) & N1_6_2_MASK));
+	si570_update_rfreq(client, data);
+	i2c_smbus_write_byte_data(client, SI570_REG_FREEZE_DCO,
+				  0);
+	i2c_smbus_write_byte_data(client, SI570_REG_CONTROL,
+				  SI570_CNTRL_NEWFREQ);
+	return 0;
+}
+
+/*
+ * Reset chip.
+ * This function must be called with update mutex lock held.
+ */
+static int si570_reset(struct i2c_client *client, struct si570_data *data)
+{
+	i2c_smbus_write_byte_data(client, SI570_REG_CONTROL,
+				  SI570_CNTRL_RESET);
+	usleep_range(1000, 5000);
+	return si570_set_frequency(client, data, data->frequency);
+}
+
+static ssize_t show_frequency_attr(struct device *dev,
+			      struct device_attribute *devattr,
+			      char *buf)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct si570_data *data = i2c_get_clientdata(client);
+
+	return sprintf(buf, "%llu\n", data->frequency);
+}
+
+int get_frequency_si570(struct device *dev, unsigned long *freq)
+{
+	int err;
+	char buf[10+1];
+
+	if ((!dev) || (to_i2c_client(dev) != si570_client))
+		return -EINVAL;
+
+	show_frequency_attr(dev, NULL, buf);
+
+	err = kstrtoul(buf, 10, freq);
+	if (err)
+		return err;
+
+	return 0;
+}
+EXPORT_SYMBOL(get_frequency_si570);
+
+static ssize_t set_frequency_attr(struct device *dev,
+			     struct device_attribute *attr,
+			     const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct si570_data *data = i2c_get_clientdata(client);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
+
+	if (val < SI570_MIN_FREQ || val > data->max_freq) {
+		dev_err(&client->dev,
+			"requested frequency %lu Hz is out of range\n", val);
+		return -EINVAL;
+	}
+
+	mutex_lock(&data->lock);
+
+	if (div64_u64(abs(val - data->frequency) * 10000LL,
+		data->frequency) < 35)
+		err = si570_set_frequency_small(client, data, val);
+	else
+		err = si570_set_frequency(client, data, val);
+	mutex_unlock(&data->lock);
+	if (err) {
+		dev_warn(&client->dev,
+			"unable to set output frequency %lu Hz: %d\n",
+			val, err);
+		return err;
+	}
+
+	dev_info(&client->dev,
+		"set new output frequency %lu Hz\n", val);
+
+	return count;
+}
+
+int set_frequency_si570(struct device *dev, unsigned long freq)
+{
+	char buf[10+1];
+
+	if ((!dev) || (to_i2c_client(dev) != si570_client))
+		return -EINVAL;
+
+	sprintf(buf, "%lu", freq);
+
+	return set_frequency_attr(dev, NULL, buf,  0);
+}
+EXPORT_SYMBOL(set_frequency_si570);
+
+static ssize_t show_reset_attr(struct device *dev,
+			  struct device_attribute *devattr,
+			  char *buf)
+{
+	return sprintf(buf, "%d\n", 0);
+}
+
+static ssize_t set_reset_attr(struct device *dev,
+			 struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct si570_data *data = i2c_get_clientdata(client);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
+	if (val == 0)
+		goto done;
+
+	mutex_lock(&data->lock);
+	err = si570_reset(client, data);
+	mutex_unlock(&data->lock);
+	if (err)
+		return err;
+done:
+	return count;
+}
+
+int reset_si570(struct device *dev, int id)
+{
+	char buf[4];
+
+	if ((!dev) || (to_i2c_client(dev) != si570_client))
+		return -EINVAL;
+
+	sprintf(buf, "%lu", (unsigned long)id);
+	return set_reset_attr(dev, NULL, buf, 0);
+}
+EXPORT_SYMBOL(reset_si570);
+
+struct i2c_client *get_i2c_client_si570(void)
+{
+	return si570_client;
+}
+EXPORT_SYMBOL(get_i2c_client_si570);
+
+static DEVICE_ATTR(frequency, S_IWUSR | S_IRUGO, show_frequency_attr,
+		   set_frequency_attr);
+static DEVICE_ATTR(reset, S_IWUSR | S_IRUGO, show_reset_attr, set_reset_attr);
+
+static struct attribute *si570_attr[] = {
+	&dev_attr_frequency.attr,
+	&dev_attr_reset.attr,
+	NULL
+};
+
+static const struct i2c_device_id si570_id[] = {
+	{ "si570", 0 },
+	{ "si571", 0 },
+	{ "si598", 1 },
+	{ "si599", 1 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, si570_id);
+
+static int si570_probe(struct i2c_client *client,
+		       const struct i2c_device_id *id)
+{
+	struct si570_platform_data *pdata = client->dev.platform_data;
+	struct si570_data *data;
+	int err;
+	unsigned long initial_fout;
+	u32 tmp = SI570_FOUT_FACTORY_DFLT;
+
+	data = kzalloc(sizeof(struct si570_data), GFP_KERNEL);
+	if (!data) {
+		err = -ENOMEM;
+		goto exit;
+	}
+
+	if (id->driver_data) {
+		data->fout = SI598_FOUT_FACTORY_DFLT;
+		data->max_freq = SI598_MAX_FREQ;
+	} else {
+		data->fout = SI570_FOUT_FACTORY_DFLT;
+		data->max_freq = SI570_MAX_FREQ;
+	}
+
+	if (pdata && pdata->factory_fout)
+		data->fout = pdata->factory_fout;
+
+	if (client->dev.of_node &&
+		(of_property_read_u32(client->dev.of_node, "factory-fout",
+			&tmp) < 0))
+		dev_warn(&client->dev,
+			"DTS does not contain factory-fout, using default\n");
+	else
+		data->fout = tmp;
+
+	i2c_set_clientdata(client, data);
+	err = si570_get_defaults(client);
+	if (err < 0)
+		goto exit_free;
+
+	mutex_init(&data->lock);
+
+	/* Register sysfs hooks */
+	data->attrs.attrs = si570_attr;
+	err = sysfs_create_group(&client->dev.kobj, &data->attrs);
+	if (err)
+		goto exit_free;
+
+	/* Display a message indicating that we've successfully registered */
+	dev_info(&client->dev,
+		"registered %s with default frequency %llu Hz\n",
+		id->name, data->fout);
+
+	/* Read the requested initial fout from either platform data or the
+	 * device tree
+	 */
+	initial_fout = 0;
+	if (pdata && pdata->initial_fout)
+		initial_fout = pdata->initial_fout;
+	if (client->dev.of_node) {
+		of_property_read_u32(client->dev.of_node, "initial-fout",
+			(u32 *)&initial_fout);
+		if (pdata && pdata->initial_fout &&
+			(pdata->initial_fout != initial_fout)) {
+			dev_warn(&client->dev,
+				"OF initial fout %lu overrides platform data fout %lu\n",
+				initial_fout,
+				pdata->initial_fout);
+		}
+	}
+
+	if (initial_fout != 0) {
+		if (initial_fout < SI570_MIN_FREQ ||
+			initial_fout > data->max_freq) {
+			dev_err(&client->dev,
+				"requested initial frequency %lu is out of range, using default\n",
+				initial_fout);
+			return 0;
+		}
+
+		mutex_lock(&data->lock);
+
+		if (div64_u64(abs(initial_fout - data->frequency) *
+			10000LL, data->frequency) < 35)
+			err = si570_set_frequency_small(client, data,
+				initial_fout);
+		else
+			err = si570_set_frequency(client, data,
+				initial_fout);
+		mutex_unlock(&data->lock);
+		if (err) {
+			dev_warn(&client->dev,
+				"unable to set initial output frequency %lu: %d\n",
+				initial_fout, err);
+			return err;
+		}
+
+		dev_info(&client->dev,
+			"set initial output frequency %lu Hz\n",
+			initial_fout);
+	}
+
+	si570_client = client;
+
+	return 0;
+
+exit_free:
+	kfree(data);
+exit:
+	return err;
+}
+
+static int si570_remove(struct i2c_client *client)
+{
+	struct si570_data *data = i2c_get_clientdata(client);
+
+	sysfs_remove_group(&client->dev.kobj, &data->attrs);
+	kfree(data);
+	return 0;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id i2c_si570_of_match[] = {
+	{ .compatible = "si570" },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, i2c_si570_of_match);
+#endif
+
+static struct i2c_driver si570_driver = {
+	.driver = {
+		.name	= "si570",
+		.of_match_table = of_match_ptr(i2c_si570_of_match),
+	},
+	.probe		= si570_probe,
+	.remove		= si570_remove,
+	.id_table	= si570_id,
+};
+
+static int __init si570_init(void)
+{
+	return i2c_add_driver(&si570_driver);
+}
+
+static void __exit si570_exit(void)
+{
+	i2c_del_driver(&si570_driver);
+}
+
+MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>");
+MODULE_DESCRIPTION("Si570 driver");
+MODULE_LICENSE("GPL");
+
+module_init(si570_init);
+module_exit(si570_exit);
diff --git a/include/linux/i2c/si570.h b/include/linux/i2c/si570.h
new file mode 100644
index 0000000..f2cf285
--- /dev/null
+++ b/include/linux/i2c/si570.h
@@ -0,0 +1,31 @@ 
+/*
+ * si570.h - Configuration for si570 misc driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation (version 2 of the License only).
+ *
+ * This program is distributed in the hope that 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.
+ */
+
+#ifndef __LINUX_SI570_H
+#define __LINUX_SI570_H
+
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+
+struct si570_platform_data {
+	u64 factory_fout;		/* Factory default output frequency */
+	unsigned long initial_fout;	/* Requested initial frequency */
+};
+
+int get_frequency_si570(struct device *dev, unsigned long *freq);
+int set_frequency_si570(struct device *dev, unsigned long freq);
+int reset_si570(struct device *dev, int id);
+struct i2c_client *get_i2c_client_si570(void);
+
+#endif /* __LINUX_SI570_H */