aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorTomoya MORINAGA <tomoya-linux@dsn.okisemi.com>2011-03-01 00:16:23 -0500
committerBen Dooks <ben-linux@fluff.org>2011-03-01 19:36:13 -0500
commit173442f2787c88e1ed1bb62aaeb6fd9127720559 (patch)
treef939237b918ee563c61d9083b649c04a8f0c3ff1 /drivers/i2c
parent493f3358cb289ccf716c5a14fa5bb52ab75943e5 (diff)
i2c-eg20t: support new device OKI SEMICONDUCTOR ML7213 IOH
Support new device OKI SEMICONDUCTOR ML7213 IOH. The ML7213 which is for IVI(In-Vehicle Infotainment) is a companion chip for the Atom E6xx series and compatible with the Intel EG20T PCH. Signed-off-by: Tomoya MORINAGA <tomoya-linux@dsn.okisemi.com> Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/Kconfig15
-rw-r--r--drivers/i2c/busses/i2c-eg20t.c161
2 files changed, 108 insertions, 68 deletions
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 113505a6434e..5b592dfcbd78 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -639,12 +639,15 @@ config I2C_XILINX
639 will be called xilinx_i2c. 639 will be called xilinx_i2c.
640 640
641config I2C_EG20T 641config I2C_EG20T
642 tristate "PCH I2C of Intel EG20T" 642 tristate "Intel EG20T PCH/OKI SEMICONDUCTOR ML7213 IOH"
643 depends on PCI 643 depends on PCI
644 help 644 help
645 This driver is for PCH(Platform controller Hub) I2C of EG20T which 645 This driver is for PCH(Platform controller Hub) I2C of EG20T which
646 is an IOH(Input/Output Hub) for x86 embedded processor. 646 is an IOH(Input/Output Hub) for x86 embedded processor.
647 This driver can access PCH I2C bus device. 647 This driver can access PCH I2C bus device.
648
649 This driver also supports the ML7213, a companion chip for the
650 Atom E6xx series and compatible with the Intel EG20T PCH.
648 651
649comment "External I2C/SMBus adapter drivers" 652comment "External I2C/SMBus adapter drivers"
650 653
diff --git a/drivers/i2c/busses/i2c-eg20t.c b/drivers/i2c/busses/i2c-eg20t.c
index 2e067dd2ee51..c57c83734692 100644
--- a/drivers/i2c/busses/i2c-eg20t.c
+++ b/drivers/i2c/busses/i2c-eg20t.c
@@ -131,6 +131,13 @@
131#define pch_pci_dbg(pdev, fmt, arg...) \ 131#define pch_pci_dbg(pdev, fmt, arg...) \
132 dev_dbg(&pdev->dev, "%s :" fmt, __func__, ##arg) 132 dev_dbg(&pdev->dev, "%s :" fmt, __func__, ##arg)
133 133
134/*
135Set the number of I2C instance max
136Intel EG20T PCH : 1ch
137OKI SEMICONDUCTOR ML7213 IOH : 2ch
138*/
139#define PCH_I2C_MAX_DEV 2
140
134/** 141/**
135 * struct i2c_algo_pch_data - for I2C driver functionalities 142 * struct i2c_algo_pch_data - for I2C driver functionalities
136 * @pch_adapter: stores the reference to i2c_adapter structure 143 * @pch_adapter: stores the reference to i2c_adapter structure
@@ -155,12 +162,14 @@ struct i2c_algo_pch_data {
155 * @pch_data: stores a list of i2c_algo_pch_data 162 * @pch_data: stores a list of i2c_algo_pch_data
156 * @pch_i2c_suspended: specifies whether the system is suspended or not 163 * @pch_i2c_suspended: specifies whether the system is suspended or not
157 * perhaps with more lines and words. 164 * perhaps with more lines and words.
165 * @ch_num: specifies the number of i2c instance
158 * 166 *
159 * pch_data has as many elements as maximum I2C channels 167 * pch_data has as many elements as maximum I2C channels
160 */ 168 */
161struct adapter_info { 169struct adapter_info {
162 struct i2c_algo_pch_data pch_data; 170 struct i2c_algo_pch_data pch_data[PCH_I2C_MAX_DEV];
163 bool pch_i2c_suspended; 171 bool pch_i2c_suspended;
172 int ch_num;
164}; 173};
165 174
166 175
@@ -169,8 +178,13 @@ static int pch_clk = 50000; /* specifies I2C clock speed in KHz */
169static wait_queue_head_t pch_event; 178static wait_queue_head_t pch_event;
170static DEFINE_MUTEX(pch_mutex); 179static DEFINE_MUTEX(pch_mutex);
171 180
181/* Definition for ML7213 by OKI SEMICONDUCTOR */
182#define PCI_VENDOR_ID_ROHM 0x10DB
183#define PCI_DEVICE_ID_ML7213_I2C 0x802D
184
172static struct pci_device_id __devinitdata pch_pcidev_id[] = { 185static struct pci_device_id __devinitdata pch_pcidev_id[] = {
173 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PCH_I2C)}, 186 { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_PCH_I2C), 1, },
187 { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_I2C), 2, },
174 {0,} 188 {0,}
175}; 189};
176 190
@@ -211,8 +225,7 @@ static void pch_i2c_init(struct i2c_algo_pch_data *adap)
211 /* Initialize I2C registers */ 225 /* Initialize I2C registers */
212 iowrite32(0x21, p + PCH_I2CNF); 226 iowrite32(0x21, p + PCH_I2CNF);
213 227
214 pch_setbit(adap->pch_base_address, PCH_I2CCTL, 228 pch_setbit(adap->pch_base_address, PCH_I2CCTL, PCH_I2CCTL_I2CMEN);
215 PCH_I2CCTL_I2CMEN);
216 229
217 if (pch_i2c_speed != 400) 230 if (pch_i2c_speed != 400)
218 pch_i2c_speed = 100; 231 pch_i2c_speed = 100;
@@ -254,7 +267,7 @@ static inline bool ktime_lt(const ktime_t cmp1, const ktime_t cmp2)
254 * @timeout: waiting time counter (us). 267 * @timeout: waiting time counter (us).
255 */ 268 */
256static s32 pch_i2c_wait_for_bus_idle(struct i2c_algo_pch_data *adap, 269static s32 pch_i2c_wait_for_bus_idle(struct i2c_algo_pch_data *adap,
257 s32 timeout) 270 s32 timeout)
258{ 271{
259 void __iomem *p = adap->pch_base_address; 272 void __iomem *p = adap->pch_base_address;
260 273
@@ -474,8 +487,8 @@ static void pch_i2c_sendnack(struct i2c_algo_pch_data *adap)
474 * @last: specifies whether last message or not. 487 * @last: specifies whether last message or not.
475 * @first: specifies whether first message or not. 488 * @first: specifies whether first message or not.
476 */ 489 */
477s32 pch_i2c_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, 490static s32 pch_i2c_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
478 u32 last, u32 first) 491 u32 last, u32 first)
479{ 492{
480 struct i2c_algo_pch_data *adap = i2c_adap->algo_data; 493 struct i2c_algo_pch_data *adap = i2c_adap->algo_data;
481 494
@@ -568,10 +581,10 @@ s32 pch_i2c_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
568} 581}
569 582
570/** 583/**
571 * pch_i2c_cb_ch0() - Interrupt handler Call back function 584 * pch_i2c_cb() - Interrupt handler Call back function
572 * @adap: Pointer to struct i2c_algo_pch_data. 585 * @adap: Pointer to struct i2c_algo_pch_data.
573 */ 586 */
574static void pch_i2c_cb_ch0(struct i2c_algo_pch_data *adap) 587static void pch_i2c_cb(struct i2c_algo_pch_data *adap)
575{ 588{
576 u32 sts; 589 u32 sts;
577 void __iomem *p = adap->pch_base_address; 590 void __iomem *p = adap->pch_base_address;
@@ -599,24 +612,30 @@ static void pch_i2c_cb_ch0(struct i2c_algo_pch_data *adap)
599 */ 612 */
600static irqreturn_t pch_i2c_handler(int irq, void *pData) 613static irqreturn_t pch_i2c_handler(int irq, void *pData)
601{ 614{
602 s32 reg_val; 615 u32 reg_val;
603 616 int flag;
604 struct i2c_algo_pch_data *adap_data = (struct i2c_algo_pch_data *)pData; 617 int i;
605 void __iomem *p = adap_data->pch_base_address; 618 struct adapter_info *adap_info = pData;
606 u32 mode = ioread32(p + PCH_I2CMOD) & (BUFFER_MODE | EEPROM_SR_MODE); 619 void __iomem *p;
607 620 u32 mode;
608 if (mode != NORMAL_MODE) { 621
609 pch_err(adap_data, "I2C mode is not supported\n"); 622 for (i = 0, flag = 0; i < adap_info->ch_num; i++) {
610 return IRQ_NONE; 623 p = adap_info->pch_data[i].pch_base_address;
624 mode = ioread32(p + PCH_I2CMOD);
625 mode &= BUFFER_MODE | EEPROM_SR_MODE;
626 if (mode != NORMAL_MODE) {
627 pch_err(adap_info->pch_data,
628 "I2C-%d mode(%d) is not supported\n", mode, i);
629 continue;
630 }
631 reg_val = ioread32(p + PCH_I2CSR);
632 if (reg_val & (I2CMAL_BIT | I2CMCF_BIT | I2CMIF_BIT)) {
633 pch_i2c_cb(&adap_info->pch_data[i]);
634 flag = 1;
635 }
611 } 636 }
612 637
613 reg_val = ioread32(p + PCH_I2CSR); 638 return flag ? IRQ_HANDLED : IRQ_NONE;
614 if (reg_val & (I2CMAL_BIT | I2CMCF_BIT | I2CMIF_BIT))
615 pch_i2c_cb_ch0(adap_data);
616 else
617 return IRQ_NONE;
618
619 return IRQ_HANDLED;
620} 639}
621 640
622/** 641/**
@@ -626,7 +645,7 @@ static irqreturn_t pch_i2c_handler(int irq, void *pData)
626 * @num: number of messages. 645 * @num: number of messages.
627 */ 646 */
628static s32 pch_i2c_xfer(struct i2c_adapter *i2c_adap, 647static s32 pch_i2c_xfer(struct i2c_adapter *i2c_adap,
629 struct i2c_msg *msgs, s32 num) 648 struct i2c_msg *msgs, s32 num)
630{ 649{
631 struct i2c_msg *pmsg; 650 struct i2c_msg *pmsg;
632 u32 i = 0; 651 u32 i = 0;
@@ -709,11 +728,13 @@ static void pch_i2c_disbl_int(struct i2c_algo_pch_data *adap)
709} 728}
710 729
711static int __devinit pch_i2c_probe(struct pci_dev *pdev, 730static int __devinit pch_i2c_probe(struct pci_dev *pdev,
712 const struct pci_device_id *id) 731 const struct pci_device_id *id)
713{ 732{
714 void __iomem *base_addr; 733 void __iomem *base_addr;
715 s32 ret; 734 int ret;
735 int i, j;
716 struct adapter_info *adap_info; 736 struct adapter_info *adap_info;
737 struct i2c_adapter *pch_adap;
717 738
718 pch_pci_dbg(pdev, "Entered.\n"); 739 pch_pci_dbg(pdev, "Entered.\n");
719 740
@@ -743,44 +764,48 @@ static int __devinit pch_i2c_probe(struct pci_dev *pdev,
743 goto err_pci_iomap; 764 goto err_pci_iomap;
744 } 765 }
745 766
746 adap_info->pch_i2c_suspended = false; 767 /* Set the number of I2C channel instance */
768 adap_info->ch_num = id->driver_data;
747 769
748 adap_info->pch_data.p_adapter_info = adap_info; 770 for (i = 0; i < adap_info->ch_num; i++) {
771 pch_adap = &adap_info->pch_data[i].pch_adapter;
772 adap_info->pch_i2c_suspended = false;
749 773
750 adap_info->pch_data.pch_adapter.owner = THIS_MODULE; 774 adap_info->pch_data[i].p_adapter_info = adap_info;
751 adap_info->pch_data.pch_adapter.class = I2C_CLASS_HWMON;
752 strcpy(adap_info->pch_data.pch_adapter.name, KBUILD_MODNAME);
753 adap_info->pch_data.pch_adapter.algo = &pch_algorithm;
754 adap_info->pch_data.pch_adapter.algo_data =
755 &adap_info->pch_data;
756 775
757 /* (i * 0x80) + base_addr; */ 776 pch_adap->owner = THIS_MODULE;
758 adap_info->pch_data.pch_base_address = base_addr; 777 pch_adap->class = I2C_CLASS_HWMON;
778 strcpy(pch_adap->name, KBUILD_MODNAME);
779 pch_adap->algo = &pch_algorithm;
780 pch_adap->algo_data = &adap_info->pch_data[i];
759 781
760 adap_info->pch_data.pch_adapter.dev.parent = &pdev->dev; 782 /* base_addr + offset; */
783 adap_info->pch_data[i].pch_base_address = base_addr + 0x100 * i;
761 784
762 ret = i2c_add_adapter(&(adap_info->pch_data.pch_adapter)); 785 pch_adap->dev.parent = &pdev->dev;
763 786
764 if (ret) { 787 ret = i2c_add_adapter(pch_adap);
765 pch_pci_err(pdev, "i2c_add_adapter FAILED\n"); 788 if (ret) {
766 goto err_i2c_add_adapter; 789 pch_pci_err(pdev, "i2c_add_adapter[ch:%d] FAILED\n", i);
767 } 790 goto err_i2c_add_adapter;
791 }
768 792
769 pch_i2c_init(&adap_info->pch_data); 793 pch_i2c_init(&adap_info->pch_data[i]);
794 }
770 ret = request_irq(pdev->irq, pch_i2c_handler, IRQF_SHARED, 795 ret = request_irq(pdev->irq, pch_i2c_handler, IRQF_SHARED,
771 KBUILD_MODNAME, &adap_info->pch_data); 796 KBUILD_MODNAME, adap_info);
772 if (ret) { 797 if (ret) {
773 pch_pci_err(pdev, "request_irq FAILED\n"); 798 pch_pci_err(pdev, "request_irq FAILED\n");
774 goto err_request_irq; 799 goto err_i2c_add_adapter;
775 } 800 }
776 801
777 pci_set_drvdata(pdev, adap_info); 802 pci_set_drvdata(pdev, adap_info);
778 pch_pci_dbg(pdev, "returns %d.\n", ret); 803 pch_pci_dbg(pdev, "returns %d.\n", ret);
779 return 0; 804 return 0;
780 805
781err_request_irq:
782 i2c_del_adapter(&(adap_info->pch_data.pch_adapter));
783err_i2c_add_adapter: 806err_i2c_add_adapter:
807 for (j = 0; j < i; j++)
808 i2c_del_adapter(&adap_info->pch_data[j].pch_adapter);
784 pci_iounmap(pdev, base_addr); 809 pci_iounmap(pdev, base_addr);
785err_pci_iomap: 810err_pci_iomap:
786 pci_release_regions(pdev); 811 pci_release_regions(pdev);
@@ -793,17 +818,22 @@ err_pci_enable:
793 818
794static void __devexit pch_i2c_remove(struct pci_dev *pdev) 819static void __devexit pch_i2c_remove(struct pci_dev *pdev)
795{ 820{
821 int i;
796 struct adapter_info *adap_info = pci_get_drvdata(pdev); 822 struct adapter_info *adap_info = pci_get_drvdata(pdev);
797 823
798 pch_i2c_disbl_int(&adap_info->pch_data); 824 free_irq(pdev->irq, adap_info);
799 free_irq(pdev->irq, &adap_info->pch_data);
800 i2c_del_adapter(&(adap_info->pch_data.pch_adapter));
801 825
802 if (adap_info->pch_data.pch_base_address) { 826 for (i = 0; i < adap_info->ch_num; i++) {
803 pci_iounmap(pdev, adap_info->pch_data.pch_base_address); 827 pch_i2c_disbl_int(&adap_info->pch_data[i]);
804 adap_info->pch_data.pch_base_address = 0; 828 i2c_del_adapter(&adap_info->pch_data[i].pch_adapter);
805 } 829 }
806 830
831 if (adap_info->pch_data[0].pch_base_address)
832 pci_iounmap(pdev, adap_info->pch_data[0].pch_base_address);
833
834 for (i = 0; i < adap_info->ch_num; i++)
835 adap_info->pch_data[i].pch_base_address = 0;
836
807 pci_set_drvdata(pdev, NULL); 837 pci_set_drvdata(pdev, NULL);
808 838
809 pci_release_regions(pdev); 839 pci_release_regions(pdev);
@@ -816,17 +846,22 @@ static void __devexit pch_i2c_remove(struct pci_dev *pdev)
816static int pch_i2c_suspend(struct pci_dev *pdev, pm_message_t state) 846static int pch_i2c_suspend(struct pci_dev *pdev, pm_message_t state)
817{ 847{
818 int ret; 848 int ret;
849 int i;
819 struct adapter_info *adap_info = pci_get_drvdata(pdev); 850 struct adapter_info *adap_info = pci_get_drvdata(pdev);
820 void __iomem *p = adap_info->pch_data.pch_base_address; 851 void __iomem *p = adap_info->pch_data[0].pch_base_address;
821 852
822 adap_info->pch_i2c_suspended = true; 853 adap_info->pch_i2c_suspended = true;
823 854
824 while ((adap_info->pch_data.pch_i2c_xfer_in_progress)) { 855 for (i = 0; i < adap_info->ch_num; i++) {
825 /* Wait until all channel transfers are completed */ 856 while ((adap_info->pch_data[i].pch_i2c_xfer_in_progress)) {
826 msleep(20); 857 /* Wait until all channel transfers are completed */
858 msleep(20);
859 }
827 } 860 }
861
828 /* Disable the i2c interrupts */ 862 /* Disable the i2c interrupts */
829 pch_i2c_disbl_int(&adap_info->pch_data); 863 for (i = 0; i < adap_info->ch_num; i++)
864 pch_i2c_disbl_int(&adap_info->pch_data[i]);
830 865
831 pch_pci_dbg(pdev, "I2CSR = %x I2CBUFSTA = %x I2CESRSTA = %x " 866 pch_pci_dbg(pdev, "I2CSR = %x I2CBUFSTA = %x I2CESRSTA = %x "
832 "invoked function pch_i2c_disbl_int successfully\n", 867 "invoked function pch_i2c_disbl_int successfully\n",
@@ -849,6 +884,7 @@ static int pch_i2c_suspend(struct pci_dev *pdev, pm_message_t state)
849 884
850static int pch_i2c_resume(struct pci_dev *pdev) 885static int pch_i2c_resume(struct pci_dev *pdev)
851{ 886{
887 int i;
852 struct adapter_info *adap_info = pci_get_drvdata(pdev); 888 struct adapter_info *adap_info = pci_get_drvdata(pdev);
853 889
854 pci_set_power_state(pdev, PCI_D0); 890 pci_set_power_state(pdev, PCI_D0);
@@ -861,7 +897,8 @@ static int pch_i2c_resume(struct pci_dev *pdev)
861 897
862 pci_enable_wake(pdev, PCI_D3hot, 0); 898 pci_enable_wake(pdev, PCI_D3hot, 0);
863 899
864 pch_i2c_init(&adap_info->pch_data); 900 for (i = 0; i < adap_info->ch_num; i++)
901 pch_i2c_init(&adap_info->pch_data[i]);
865 902
866 adap_info->pch_i2c_suspended = false; 903 adap_info->pch_i2c_suspended = false;
867 904
@@ -893,7 +930,7 @@ static void __exit pch_pci_exit(void)
893} 930}
894module_exit(pch_pci_exit); 931module_exit(pch_pci_exit);
895 932
896MODULE_DESCRIPTION("PCH I2C PCI Driver"); 933MODULE_DESCRIPTION("Intel EG20T PCH/OKI SEMICONDUCTOR ML7213 IOH I2C Driver");
897MODULE_LICENSE("GPL"); 934MODULE_LICENSE("GPL");
898MODULE_AUTHOR("Tomoya MORINAGA. <tomoya-linux@dsn.okisemi.com>"); 935MODULE_AUTHOR("Tomoya MORINAGA. <tomoya-linux@dsn.okisemi.com>");
899module_param(pch_i2c_speed, int, (S_IRUSR | S_IWUSR)); 936module_param(pch_i2c_speed, int, (S_IRUSR | S_IWUSR));