static int i2c_lpc2k_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct lpc2k_i2c *i2c = platform_get_drvdata(pdev); clk_enable(i2c->clk); i2c_lpc2k_reset(i2c); return 0; }
static int i2c_lpc2k_clear_arb(struct lpc2k_i2c *i2c) { unsigned long timeout = jiffies + msecs_to_jiffies(1000); /* * If the transfer needs to abort for some reason, we'll try to * force a stop condition to clear any pending bus conditions */ writel(LPC24XX_STO, i2c->base + LPC24XX_I2CONSET); /* Wait for status change */ while (readl(i2c->base + LPC24XX_I2STAT) != M_I2C_IDLE) { if (time_after(jiffies, timeout)) { /* Bus was not idle, try to reset adapter */ i2c_lpc2k_reset(i2c); return -EBUSY; } cpu_relax(); } return 0; }
static int i2c_lpc2k_clear_arb(struct lpc2k_i2c *i2c) { long timeout = jiffies + HZ; int ret = 0; /* * If the transfer needs to abort for some reason, we'll try to * force a stop condition to clear any pending bus conditions */ i2c_writel(LPC24XX_STO, i2c->reg_base + LPC24XX_I2CONSET); /* Wait for status change */ while (jiffies < timeout && (i2c_readl(i2c->reg_base + LPC24XX_I2STAT) != m_i2c_idle)) cpu_relax(); if (i2c_readl(i2c->reg_base + LPC24XX_I2STAT) != m_i2c_idle) { /* Bus was not idle, try to reset adapter */ i2c_lpc2k_reset(i2c); ret = -EBUSY; } return ret; }
static int i2c_lpc2k_probe(struct platform_device *dev) { struct lpc2k_i2c *i2c; struct resource *res; int ret, irq; unsigned long clkrate; res = platform_get_resource(dev, IORESOURCE_MEM, 0); irq = platform_get_irq(dev, 0); if (res == NULL || irq < 0) { dev_err(&dev->dev, "No resource data!\n"); return -ENODEV; } if (dev->id < 0 || dev->id >= LPC24XX_MAX_ADAPTERS) { dev_err(&dev->dev, "I2C bus number invalid (%d)\n", dev->id); return -ENODEV; } if (!request_mem_region(res->start, resource_size(res), res->name)) { dev_err(&dev->dev, "Memory region already used!\n"); return -ENOMEM; } i2c = kzalloc(sizeof(struct lpc2k_i2c), GFP_KERNEL); if (!i2c) { dev_err(&dev->dev, "Error allocating memory!\n"); ret = -ENOMEM; goto emalloc; } i2c->adap.owner = THIS_MODULE; init_waitqueue_head(&i2c->wait); i2c->adap.nr = dev->id; snprintf(i2c->adap.name, sizeof(i2c->adap.name), MODULE_NAME ".%u", i2c->adap.nr); i2c->clk = clk_get(&dev->dev, NULL); if (IS_ERR(i2c->clk)) { dev_err(&dev->dev, "Error getting clock!\n"); ret = PTR_ERR(i2c->clk); goto eclk; } i2c->reg_base = ioremap(res->start, resource_size(res)); if (!i2c->reg_base) { dev_err(&dev->dev, "Error mapping memory!\n"); ret = -EIO; goto eremap; } i2c->iobase = res->start; i2c->iosize = resource_size(res); i2c->irq = irq; clk_enable(i2c->clk); i2c->adap.algo = &i2c_lpc2k_algorithm; ret = request_irq(irq, i2c_lpc2k_handler, IRQF_DISABLED, i2c->adap.name, i2c); if (ret) goto ereqirq; disable_irq_nosync(irq); i2c_lpc2k_reset(i2c); i2c->adap.algo_data = i2c; i2c->adap.dev.parent = &dev->dev; ret = i2c_add_numbered_adapter(&i2c->adap); if (ret < 0) { dev_err(&dev->dev, "Failed to add bus!\n"); goto eadapt; } platform_set_drvdata(dev, i2c); printk(KERN_INFO "I2C: %s: LPC2K I2C adapter\n", dev_name(&i2c->adap.dev)); /* Place controller is a known state */ i2c_lpc2k_reset(i2c); /* Get I2C base clock rate */ clkrate = clk_get_rate(i2c->clk); if (!clkrate) { dev_warn(&dev->dev, "Can't get I2C base clock, using " "12MHz!\n"); clkrate = 12000000; } /* Setup I2C dividers to generate clock rate with 50% duty cycle */ clkrate = (clkrate / scl_frequency) / 2; i2c_writel(clkrate, i2c->reg_base + LPC24XX_I2SCLL); i2c_writel(clkrate, i2c->reg_base + LPC24XX_I2SCLH); return 0; eadapt: free_irq(irq, i2c); ereqirq: clk_disable(i2c->clk); iounmap(i2c->reg_base); eremap: clk_put(i2c->clk); eclk: kfree(i2c); emalloc: release_mem_region(res->start, resource_size(res)); return ret; }
static int i2c_lpc2k_probe(struct platform_device *pdev) { struct lpc2k_i2c *i2c; struct resource *res; u32 bus_clk_rate; u32 scl_high; u32 clkrate; int ret; i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL); if (!i2c) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); i2c->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(i2c->base)) return PTR_ERR(i2c->base); i2c->irq = platform_get_irq(pdev, 0); if (i2c->irq < 0) { dev_err(&pdev->dev, "can't get interrupt resource\n"); return i2c->irq; } init_waitqueue_head(&i2c->wait); i2c->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(i2c->clk)) { dev_err(&pdev->dev, "error getting clock\n"); return PTR_ERR(i2c->clk); } ret = clk_prepare_enable(i2c->clk); if (ret) { dev_err(&pdev->dev, "unable to enable clock.\n"); return ret; } ret = devm_request_irq(&pdev->dev, i2c->irq, i2c_lpc2k_handler, 0, dev_name(&pdev->dev), i2c); if (ret < 0) { dev_err(&pdev->dev, "can't request interrupt.\n"); goto fail_clk; } disable_irq_nosync(i2c->irq); /* Place controller is a known state */ i2c_lpc2k_reset(i2c); ret = of_property_read_u32(pdev->dev.of_node, "clock-frequency", &bus_clk_rate); if (ret) bus_clk_rate = 100000; /* 100 kHz default clock rate */ clkrate = clk_get_rate(i2c->clk); if (clkrate == 0) { dev_err(&pdev->dev, "can't get I2C base clock\n"); ret = -EINVAL; goto fail_clk; } /* Setup I2C dividers to generate clock with proper duty cycle */ clkrate = clkrate / bus_clk_rate; if (bus_clk_rate <= 100000) scl_high = (clkrate * I2C_STD_MODE_DUTY) / 100; else if (bus_clk_rate <= 400000) scl_high = (clkrate * I2C_FAST_MODE_DUTY) / 100; else scl_high = (clkrate * I2C_FAST_MODE_PLUS_DUTY) / 100; writel(scl_high, i2c->base + LPC24XX_I2SCLH); writel(clkrate - scl_high, i2c->base + LPC24XX_I2SCLL); platform_set_drvdata(pdev, i2c); i2c_set_adapdata(&i2c->adap, i2c); i2c->adap.owner = THIS_MODULE; strlcpy(i2c->adap.name, "LPC2K I2C adapter", sizeof(i2c->adap.name)); i2c->adap.algo = &i2c_lpc2k_algorithm; i2c->adap.dev.parent = &pdev->dev; i2c->adap.dev.of_node = pdev->dev.of_node; ret = i2c_add_adapter(&i2c->adap); if (ret < 0) goto fail_clk; dev_info(&pdev->dev, "LPC2K I2C adapter\n"); return 0; fail_clk: clk_disable_unprepare(i2c->clk); return ret; }