Re: [PATCH] mfd:rtsx: Support RTS5249

2013-04-09 Thread Samuel Ortiz
Hi Wei,

On Mon, Mar 25, 2013 at 10:13:56AM +0800, wei_w...@realsil.com.cn wrote:
> diff --git a/drivers/mfd/rts5249.c b/drivers/mfd/rts5249.c
> new file mode 100644
> index 000..24a1861
> --- /dev/null
> +++ b/drivers/mfd/rts5249.c
> @@ -0,0 +1,245 @@
> +/* Driver for Realtek PCI-Express card reader
> + *
> + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
2009-2013 ?


> + *
> + * 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, 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.
> + *
> + * You should have received a copy of the GNU General Public License along
> + * with this program; if not, see .
> + *
> + * Author:
> + *   Wei WANG 
> + *   No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
> + */
> +
> +#include 
> +#include 
> +#include 
> +
> +#include "rtsx_pcr.h"
> +
> +static u8 rts5249_get_ic_version(struct rtsx_pcr *pcr)
> +{
> + u8 val;
> +
> + rtsx_pci_read_register(pcr, DUMMY_REG_RESET_0, );
> + return val & 0x0F;
> +}
> +
> +static int rts5249_extra_init_hw(struct rtsx_pcr *pcr)
> +{
> + rtsx_pci_init_cmd(pcr);
> +
> + /* Configure GPIO as output */
> + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, GPIO_CTL, 0x02, 0x02);
> + /* Switch LDO3318 source from DV33 to card_3v3 */
> + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x00);
> + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x01);
> + /* LED shine disabled, set initial shine cycle period */
> + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OLT_LED_CTL, 0x0F, 0x02);
> + /* Configure force_clock_req
> +  * Maybe We should define 0xFF03 as some name
> +  */
> + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, 0xFF03, 0x08, 0x08);
> + /* Correct driving */
> + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
> + SD30_CLK_DRIVE_SEL, 0xFF, 0x99);
> + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
> + SD30_CMD_DRIVE_SEL, 0xFF, 0x99);
> + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
> + SD30_DAT_DRIVE_SEL, 0xFF, 0x92);
> +
> + return rtsx_pci_send_cmd(pcr, 100);
> +}
> +
> +static int rts5249_optimize_phy(struct rtsx_pcr *pcr)
> +{
> + int err;
> +
> + err = rtsx_pci_write_phy_register(pcr, 0x19, 0xFE46);
There are a _lot_ of magic values in those drivers. Could we at least define
register names in the header files ?


> + if (err < 0)
> + return err;
> +
> + mdelay(1);
I second Dan here: Why do you need to busy loop ? I understand delays may be
needed, but why wouldn't an msleep be sufficient ? AFAICT, you're calling this
one from the PCI probe routine, where you could sleep.

Cheers,
Samuel.

-- 
Intel Open Source Technology Centre
http://oss.intel.com/
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] mfd:rtsx: Support RTS5249

2013-04-09 Thread Samuel Ortiz
Hi Wei,

On Mon, Mar 25, 2013 at 10:13:56AM +0800, wei_w...@realsil.com.cn wrote:
 diff --git a/drivers/mfd/rts5249.c b/drivers/mfd/rts5249.c
 new file mode 100644
 index 000..24a1861
 --- /dev/null
 +++ b/drivers/mfd/rts5249.c
 @@ -0,0 +1,245 @@
 +/* Driver for Realtek PCI-Express card reader
 + *
 + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
2009-2013 ?


 + *
 + * 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, 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.
 + *
 + * You should have received a copy of the GNU General Public License along
 + * with this program; if not, see http://www.gnu.org/licenses/.
 + *
 + * Author:
 + *   Wei WANG wei_w...@realsil.com.cn
 + *   No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
 + */
 +
 +#include linux/module.h
 +#include linux/delay.h
 +#include linux/mfd/rtsx_pci.h
 +
 +#include rtsx_pcr.h
 +
 +static u8 rts5249_get_ic_version(struct rtsx_pcr *pcr)
 +{
 + u8 val;
 +
 + rtsx_pci_read_register(pcr, DUMMY_REG_RESET_0, val);
 + return val  0x0F;
 +}
 +
 +static int rts5249_extra_init_hw(struct rtsx_pcr *pcr)
 +{
 + rtsx_pci_init_cmd(pcr);
 +
 + /* Configure GPIO as output */
 + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, GPIO_CTL, 0x02, 0x02);
 + /* Switch LDO3318 source from DV33 to card_3v3 */
 + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x00);
 + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x01);
 + /* LED shine disabled, set initial shine cycle period */
 + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OLT_LED_CTL, 0x0F, 0x02);
 + /* Configure force_clock_req
 +  * Maybe We should define 0xFF03 as some name
 +  */
 + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, 0xFF03, 0x08, 0x08);
 + /* Correct driving */
 + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
 + SD30_CLK_DRIVE_SEL, 0xFF, 0x99);
 + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
 + SD30_CMD_DRIVE_SEL, 0xFF, 0x99);
 + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
 + SD30_DAT_DRIVE_SEL, 0xFF, 0x92);
 +
 + return rtsx_pci_send_cmd(pcr, 100);
 +}
 +
 +static int rts5249_optimize_phy(struct rtsx_pcr *pcr)
 +{
 + int err;
 +
 + err = rtsx_pci_write_phy_register(pcr, 0x19, 0xFE46);
There are a _lot_ of magic values in those drivers. Could we at least define
register names in the header files ?


 + if (err  0)
 + return err;
 +
 + mdelay(1);
I second Dan here: Why do you need to busy loop ? I understand delays may be
needed, but why wouldn't an msleep be sufficient ? AFAICT, you're calling this
one from the PCI probe routine, where you could sleep.

Cheers,
Samuel.

-- 
Intel Open Source Technology Centre
http://oss.intel.com/
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] mfd:rtsx: Support RTS5249

2013-03-25 Thread Dan Carpenter
On Mon, Mar 25, 2013 at 02:23:45PM +0800, wwang wrote:
> 于 2013年03月25日 14:00, Dan Carpenter 写道:
> >On Mon, Mar 25, 2013 at 10:13:56AM +0800, wei_w...@realsil.com.cn wrote:
> >>+static int rts5249_optimize_phy(struct rtsx_pcr *pcr)
> >>+{
> >>+   int err;
> >>+
> >>+   err = rtsx_pci_write_phy_register(pcr, 0x19, 0xFE46);
> >>+   if (err < 0)
> >>+   return err;
> >>+
> >>+   mdelay(1);
> >Why do we have the mdelay() and the later msleep(5)?
> >rtsx_pci_write_phy_register() busy loops until the write succeeds or
> >it returns -ETIMEOUT.  The extra wait here seems unnecessary.
> >
> >regards,
> >dan carpenter
> >
> >
> >.
> 
> Hi,
> 
> The busy loops in rtsx_pci_write_phy_register only tell us that the
> write sequence succeeds. The device still needs to wait for a while
> until the internal signal stable. Or else the timing won't fit the
> requirement.
> All of the delays in the driver are necessary.

Ok.  Cool.

regards,
dan carpenter

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] mfd:rtsx: Support RTS5249

2013-03-25 Thread wwang

于 2013年03月25日 14:00, Dan Carpenter 写道:

On Mon, Mar 25, 2013 at 10:13:56AM +0800, wei_w...@realsil.com.cn wrote:

+static int rts5249_optimize_phy(struct rtsx_pcr *pcr)
+{
+   int err;
+
+   err = rtsx_pci_write_phy_register(pcr, 0x19, 0xFE46);
+   if (err < 0)
+   return err;
+
+   mdelay(1);

Why do we have the mdelay() and the later msleep(5)?
rtsx_pci_write_phy_register() busy loops until the write succeeds or
it returns -ETIMEOUT.  The extra wait here seems unnecessary.

regards,
dan carpenter


.
  


Hi,

The busy loops in rtsx_pci_write_phy_register only tell us that the 
write sequence succeeds. The device still needs to wait for a while 
until the internal signal stable. Or else the timing won't fit the 
requirement.

All of the delays in the driver are necessary.

BR,
Wei
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] mfd:rtsx: Support RTS5249

2013-03-25 Thread Dan Carpenter
On Mon, Mar 25, 2013 at 10:13:56AM +0800, wei_w...@realsil.com.cn wrote:
> +static int rts5249_optimize_phy(struct rtsx_pcr *pcr)
> +{
> + int err;
> +
> + err = rtsx_pci_write_phy_register(pcr, 0x19, 0xFE46);
> + if (err < 0)
> + return err;
> +
> + mdelay(1);

Why do we have the mdelay() and the later msleep(5)?
rtsx_pci_write_phy_register() busy loops until the write succeeds or
it returns -ETIMEOUT.  The extra wait here seems unnecessary.

regards,
dan carpenter


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] mfd:rtsx: Support RTS5249

2013-03-25 Thread Dan Carpenter
On Mon, Mar 25, 2013 at 10:13:56AM +0800, wei_w...@realsil.com.cn wrote:
 +static int rts5249_optimize_phy(struct rtsx_pcr *pcr)
 +{
 + int err;
 +
 + err = rtsx_pci_write_phy_register(pcr, 0x19, 0xFE46);
 + if (err  0)
 + return err;
 +
 + mdelay(1);

Why do we have the mdelay() and the later msleep(5)?
rtsx_pci_write_phy_register() busy loops until the write succeeds or
it returns -ETIMEOUT.  The extra wait here seems unnecessary.

regards,
dan carpenter


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] mfd:rtsx: Support RTS5249

2013-03-25 Thread wwang

于 2013年03月25日 14:00, Dan Carpenter 写道:

On Mon, Mar 25, 2013 at 10:13:56AM +0800, wei_w...@realsil.com.cn wrote:

+static int rts5249_optimize_phy(struct rtsx_pcr *pcr)
+{
+   int err;
+
+   err = rtsx_pci_write_phy_register(pcr, 0x19, 0xFE46);
+   if (err  0)
+   return err;
+
+   mdelay(1);

Why do we have the mdelay() and the later msleep(5)?
rtsx_pci_write_phy_register() busy loops until the write succeeds or
it returns -ETIMEOUT.  The extra wait here seems unnecessary.

regards,
dan carpenter


.
  


Hi,

The busy loops in rtsx_pci_write_phy_register only tell us that the 
write sequence succeeds. The device still needs to wait for a while 
until the internal signal stable. Or else the timing won't fit the 
requirement.

All of the delays in the driver are necessary.

BR,
Wei
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] mfd:rtsx: Support RTS5249

2013-03-25 Thread Dan Carpenter
On Mon, Mar 25, 2013 at 02:23:45PM +0800, wwang wrote:
 于 2013年03月25日 14:00, Dan Carpenter 写道:
 On Mon, Mar 25, 2013 at 10:13:56AM +0800, wei_w...@realsil.com.cn wrote:
 +static int rts5249_optimize_phy(struct rtsx_pcr *pcr)
 +{
 +   int err;
 +
 +   err = rtsx_pci_write_phy_register(pcr, 0x19, 0xFE46);
 +   if (err  0)
 +   return err;
 +
 +   mdelay(1);
 Why do we have the mdelay() and the later msleep(5)?
 rtsx_pci_write_phy_register() busy loops until the write succeeds or
 it returns -ETIMEOUT.  The extra wait here seems unnecessary.
 
 regards,
 dan carpenter
 
 
 .
 
 Hi,
 
 The busy loops in rtsx_pci_write_phy_register only tell us that the
 write sequence succeeds. The device still needs to wait for a while
 until the internal signal stable. Or else the timing won't fit the
 requirement.
 All of the delays in the driver are necessary.

Ok.  Cool.

regards,
dan carpenter

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] mfd:rtsx: Support RTS5249

2013-03-24 Thread wei_wang
From: Wei WANG 

Support new model: RTS5249

Signed-off-by: Wei WANG 
---
 drivers/mfd/Makefile |2 +-
 drivers/mfd/rts5249.c|  245 ++
 drivers/mfd/rtsx_pcr.c   |5 +
 drivers/mfd/rtsx_pcr.h   |1 +
 include/linux/mfd/rtsx_pci.h |2 +
 5 files changed, 254 insertions(+), 1 deletion(-)
 create mode 100644 drivers/mfd/rts5249.c

diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index b90409c..f61ac02 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -9,7 +9,7 @@ obj-$(CONFIG_MFD_88PM805)   += 88pm805.o 88pm80x.o
 obj-$(CONFIG_MFD_SM501)+= sm501.o
 obj-$(CONFIG_MFD_ASIC3)+= asic3.o tmio_core.o
 
-rtsx_pci-objs  := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o 
rts5227.o
+rtsx_pci-objs  := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o 
rts5227.o rts5249.o
 obj-$(CONFIG_MFD_RTSX_PCI) += rtsx_pci.o
 
 obj-$(CONFIG_HTC_EGPIO)+= htc-egpio.o
diff --git a/drivers/mfd/rts5249.c b/drivers/mfd/rts5249.c
new file mode 100644
index 000..24a1861
--- /dev/null
+++ b/drivers/mfd/rts5249.c
@@ -0,0 +1,245 @@
+/* Driver for Realtek PCI-Express card reader
+ *
+ * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * 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, 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.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see .
+ *
+ * Author:
+ *   Wei WANG 
+ *   No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
+ */
+
+#include 
+#include 
+#include 
+
+#include "rtsx_pcr.h"
+
+static u8 rts5249_get_ic_version(struct rtsx_pcr *pcr)
+{
+   u8 val;
+
+   rtsx_pci_read_register(pcr, DUMMY_REG_RESET_0, );
+   return val & 0x0F;
+}
+
+static int rts5249_extra_init_hw(struct rtsx_pcr *pcr)
+{
+   rtsx_pci_init_cmd(pcr);
+
+   /* Configure GPIO as output */
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, GPIO_CTL, 0x02, 0x02);
+   /* Switch LDO3318 source from DV33 to card_3v3 */
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x00);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x01);
+   /* LED shine disabled, set initial shine cycle period */
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OLT_LED_CTL, 0x0F, 0x02);
+   /* Configure force_clock_req
+* Maybe We should define 0xFF03 as some name
+*/
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, 0xFF03, 0x08, 0x08);
+   /* Correct driving */
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+   SD30_CLK_DRIVE_SEL, 0xFF, 0x99);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+   SD30_CMD_DRIVE_SEL, 0xFF, 0x99);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+   SD30_DAT_DRIVE_SEL, 0xFF, 0x92);
+
+   return rtsx_pci_send_cmd(pcr, 100);
+}
+
+static int rts5249_optimize_phy(struct rtsx_pcr *pcr)
+{
+   int err;
+
+   err = rtsx_pci_write_phy_register(pcr, 0x19, 0xFE46);
+   if (err < 0)
+   return err;
+
+   mdelay(1);
+
+   return rtsx_pci_write_phy_register(pcr, 0x0A, 0x05C0);
+}
+
+static int rts5249_turn_on_led(struct rtsx_pcr *pcr)
+{
+   return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x02);
+}
+
+static int rts5249_turn_off_led(struct rtsx_pcr *pcr)
+{
+   return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x00);
+}
+
+static int rts5249_enable_auto_blink(struct rtsx_pcr *pcr)
+{
+   return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x08);
+}
+
+static int rts5249_disable_auto_blink(struct rtsx_pcr *pcr)
+{
+   return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x00);
+}
+
+static int rts5249_card_power_on(struct rtsx_pcr *pcr, int card)
+{
+   int err;
+
+   rtsx_pci_init_cmd(pcr);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
+   SD_POWER_MASK, SD_VCC_PARTIAL_POWER_ON);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
+   LDO3318_PWR_MASK, 0x02);
+   err = rtsx_pci_send_cmd(pcr, 100);
+   if (err < 0)
+   return err;
+
+   msleep(5);
+
+   rtsx_pci_init_cmd(pcr);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
+   SD_POWER_MASK, SD_VCC_POWER_ON);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
+   LDO3318_PWR_MASK, 0x06);
+   err = rtsx_pci_send_cmd(pcr, 100);
+   if (err < 0)
+   

[PATCH] mfd:rtsx: Support RTS5249

2013-03-24 Thread wei_wang
From: Wei WANG wei_w...@realsil.com.cn

Support new model: RTS5249

Signed-off-by: Wei WANG wei_w...@realsil.com.cn
---
 drivers/mfd/Makefile |2 +-
 drivers/mfd/rts5249.c|  245 ++
 drivers/mfd/rtsx_pcr.c   |5 +
 drivers/mfd/rtsx_pcr.h   |1 +
 include/linux/mfd/rtsx_pci.h |2 +
 5 files changed, 254 insertions(+), 1 deletion(-)
 create mode 100644 drivers/mfd/rts5249.c

diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index b90409c..f61ac02 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -9,7 +9,7 @@ obj-$(CONFIG_MFD_88PM805)   += 88pm805.o 88pm80x.o
 obj-$(CONFIG_MFD_SM501)+= sm501.o
 obj-$(CONFIG_MFD_ASIC3)+= asic3.o tmio_core.o
 
-rtsx_pci-objs  := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o 
rts5227.o
+rtsx_pci-objs  := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o 
rts5227.o rts5249.o
 obj-$(CONFIG_MFD_RTSX_PCI) += rtsx_pci.o
 
 obj-$(CONFIG_HTC_EGPIO)+= htc-egpio.o
diff --git a/drivers/mfd/rts5249.c b/drivers/mfd/rts5249.c
new file mode 100644
index 000..24a1861
--- /dev/null
+++ b/drivers/mfd/rts5249.c
@@ -0,0 +1,245 @@
+/* Driver for Realtek PCI-Express card reader
+ *
+ * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * 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, 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.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see http://www.gnu.org/licenses/.
+ *
+ * Author:
+ *   Wei WANG wei_w...@realsil.com.cn
+ *   No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
+ */
+
+#include linux/module.h
+#include linux/delay.h
+#include linux/mfd/rtsx_pci.h
+
+#include rtsx_pcr.h
+
+static u8 rts5249_get_ic_version(struct rtsx_pcr *pcr)
+{
+   u8 val;
+
+   rtsx_pci_read_register(pcr, DUMMY_REG_RESET_0, val);
+   return val  0x0F;
+}
+
+static int rts5249_extra_init_hw(struct rtsx_pcr *pcr)
+{
+   rtsx_pci_init_cmd(pcr);
+
+   /* Configure GPIO as output */
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, GPIO_CTL, 0x02, 0x02);
+   /* Switch LDO3318 source from DV33 to card_3v3 */
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x00);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x01);
+   /* LED shine disabled, set initial shine cycle period */
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OLT_LED_CTL, 0x0F, 0x02);
+   /* Configure force_clock_req
+* Maybe We should define 0xFF03 as some name
+*/
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, 0xFF03, 0x08, 0x08);
+   /* Correct driving */
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+   SD30_CLK_DRIVE_SEL, 0xFF, 0x99);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+   SD30_CMD_DRIVE_SEL, 0xFF, 0x99);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+   SD30_DAT_DRIVE_SEL, 0xFF, 0x92);
+
+   return rtsx_pci_send_cmd(pcr, 100);
+}
+
+static int rts5249_optimize_phy(struct rtsx_pcr *pcr)
+{
+   int err;
+
+   err = rtsx_pci_write_phy_register(pcr, 0x19, 0xFE46);
+   if (err  0)
+   return err;
+
+   mdelay(1);
+
+   return rtsx_pci_write_phy_register(pcr, 0x0A, 0x05C0);
+}
+
+static int rts5249_turn_on_led(struct rtsx_pcr *pcr)
+{
+   return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x02);
+}
+
+static int rts5249_turn_off_led(struct rtsx_pcr *pcr)
+{
+   return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x00);
+}
+
+static int rts5249_enable_auto_blink(struct rtsx_pcr *pcr)
+{
+   return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x08);
+}
+
+static int rts5249_disable_auto_blink(struct rtsx_pcr *pcr)
+{
+   return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x00);
+}
+
+static int rts5249_card_power_on(struct rtsx_pcr *pcr, int card)
+{
+   int err;
+
+   rtsx_pci_init_cmd(pcr);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
+   SD_POWER_MASK, SD_VCC_PARTIAL_POWER_ON);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
+   LDO3318_PWR_MASK, 0x02);
+   err = rtsx_pci_send_cmd(pcr, 100);
+   if (err  0)
+   return err;
+
+   msleep(5);
+
+   rtsx_pci_init_cmd(pcr);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
+   SD_POWER_MASK, SD_VCC_POWER_ON);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
+