0001
0002
0003
0004
0005
0006 #include <linux/clk.h>
0007 #include <linux/delay.h>
0008 #include <linux/io.h>
0009 #include <linux/jiffies.h>
0010 #include <linux/module.h>
0011 #include <linux/mod_devicetable.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/platform_data/sgi-w1.h>
0014
0015 #include <linux/w1.h>
0016
0017 #define MCR_RD_DATA BIT(0)
0018 #define MCR_DONE BIT(1)
0019
0020 #define MCR_PACK(pulse, sample) (((pulse) << 10) | ((sample) << 2))
0021
0022 struct sgi_w1_device {
0023 u32 __iomem *mcr;
0024 struct w1_bus_master bus_master;
0025 char dev_id[64];
0026 };
0027
0028 static u8 sgi_w1_wait(u32 __iomem *mcr)
0029 {
0030 u32 mcr_val;
0031
0032 do {
0033 mcr_val = readl(mcr);
0034 } while (!(mcr_val & MCR_DONE));
0035
0036 return (mcr_val & MCR_RD_DATA) ? 1 : 0;
0037 }
0038
0039
0040
0041
0042
0043
0044 static u8 sgi_w1_reset_bus(void *data)
0045 {
0046 struct sgi_w1_device *dev = data;
0047 u8 ret;
0048
0049 writel(MCR_PACK(520, 65), dev->mcr);
0050 ret = sgi_w1_wait(dev->mcr);
0051 udelay(500);
0052 return ret;
0053 }
0054
0055
0056
0057
0058
0059
0060 static u8 sgi_w1_touch_bit(void *data, u8 bit)
0061 {
0062 struct sgi_w1_device *dev = data;
0063 u8 ret;
0064
0065 if (bit)
0066 writel(MCR_PACK(6, 13), dev->mcr);
0067 else
0068 writel(MCR_PACK(80, 30), dev->mcr);
0069
0070 ret = sgi_w1_wait(dev->mcr);
0071 if (bit)
0072 udelay(100);
0073 return ret;
0074 }
0075
0076 static int sgi_w1_probe(struct platform_device *pdev)
0077 {
0078 struct sgi_w1_device *sdev;
0079 struct sgi_w1_platform_data *pdata;
0080
0081 sdev = devm_kzalloc(&pdev->dev, sizeof(struct sgi_w1_device),
0082 GFP_KERNEL);
0083 if (!sdev)
0084 return -ENOMEM;
0085
0086 sdev->mcr = devm_platform_ioremap_resource(pdev, 0);
0087 if (IS_ERR(sdev->mcr))
0088 return PTR_ERR(sdev->mcr);
0089
0090 sdev->bus_master.data = sdev;
0091 sdev->bus_master.reset_bus = sgi_w1_reset_bus;
0092 sdev->bus_master.touch_bit = sgi_w1_touch_bit;
0093
0094 pdata = dev_get_platdata(&pdev->dev);
0095 if (pdata) {
0096 strlcpy(sdev->dev_id, pdata->dev_id, sizeof(sdev->dev_id));
0097 sdev->bus_master.dev_id = sdev->dev_id;
0098 }
0099
0100 platform_set_drvdata(pdev, sdev);
0101
0102 return w1_add_master_device(&sdev->bus_master);
0103 }
0104
0105
0106
0107
0108 static int sgi_w1_remove(struct platform_device *pdev)
0109 {
0110 struct sgi_w1_device *sdev = platform_get_drvdata(pdev);
0111
0112 w1_remove_master_device(&sdev->bus_master);
0113
0114 return 0;
0115 }
0116
0117 static struct platform_driver sgi_w1_driver = {
0118 .driver = {
0119 .name = "sgi_w1",
0120 },
0121 .probe = sgi_w1_probe,
0122 .remove = sgi_w1_remove,
0123 };
0124 module_platform_driver(sgi_w1_driver);
0125
0126 MODULE_LICENSE("GPL");
0127 MODULE_AUTHOR("Thomas Bogendoerfer");
0128 MODULE_DESCRIPTION("Driver for One-Wire IP in SGI ASICs");