Ejemplo n.º 1
0
static int i2c_versatile_probe(struct platform_device *dev)
{
	struct i2c_versatile *i2c;
	struct resource *r;
	int ret;

	r = platform_get_resource(dev, IORESOURCE_MEM, 0);
	if (!r) {
		ret = -EINVAL;
		goto err_out;
	}

	if (!request_mem_region(r->start, resource_size(r), "versatile-i2c")) {
		ret = -EBUSY;
		goto err_out;
	}

	i2c = kzalloc(sizeof(struct i2c_versatile), GFP_KERNEL);
	if (!i2c) {
		ret = -ENOMEM;
		goto err_release;
	}

	i2c->base = ioremap(r->start, resource_size(r));
	if (!i2c->base) {
		ret = -ENOMEM;
		goto err_free;
	}

	writel(SCL | SDA, i2c->base + I2C_CONTROLS);

	i2c->adap.owner = THIS_MODULE;
	strlcpy(i2c->adap.name, "Versatile I2C adapter", sizeof(i2c->adap.name));
	i2c->adap.algo_data = &i2c->algo;
	i2c->adap.dev.parent = &dev->dev;
	i2c->adap.dev.of_node = dev->dev.of_node;
	i2c->algo = i2c_versatile_algo;
	i2c->algo.data = i2c;

	i2c->adap.nr = dev->id;
	ret = i2c_bit_add_numbered_bus(&i2c->adap);
	if (ret >= 0) {
		platform_set_drvdata(dev, i2c);
		of_i2c_register_devices(&i2c->adap);
		return 0;
	}

	iounmap(i2c->base);
 err_free:
	kfree(i2c);
 err_release:
	release_mem_region(r->start, resource_size(r));
 err_out:
	return ret;
}
Ejemplo n.º 2
0
/** Shared device initialization code */
static int __devinit xilinx_iic_setup(
				struct device *device,
				struct device_node *node,
				struct resource *r_mem,
				struct resource *r_irq,
				u32 ten_bit_addr, 
				u32 gpo_width) {

	XIic_Config xiic_cfg;
	struct xiic_data *dev;
	char *scan_results;
	int error;

	/* Allocate the dev and zero it out. */
	dev = kmalloc(sizeof(struct xiic_data), GFP_KERNEL);
	if (!dev) {
		dev_err(device, "Cannot allocate struct xiic_data\n");
		error = -ENOMEM;
		goto out2;
	}
	memset(dev, 0, sizeof(struct xiic_data));

	dev_set_drvdata(device, dev);

	dev->irq = r_irq->start;

	/* initialize fields to satisfy i2c  */
	dev->index = 0;

	init_completion(&dev->complete);

	memset(&xiic_cfg, 0, sizeof(XIic_Config));
	xiic_cfg.DeviceId = 0;

	/* Change the addresses to be virtual; save the old ones to restore. */
	dev->base = r_mem->start;
	xiic_cfg.BaseAddress =
	    (u32) ioremap(r_mem->start, r_mem->end - r_mem->start + 1);

	dev->remapped = 1;
	down(&cfg_sem);

	xiic_cfg.Has10BitAddr = (int)ten_bit_addr;
	xiic_cfg.GpOutWidth = (u8)gpo_width;

	/* Tell the Xilinx code to bring this IIC interface up. */
	if (XIic_CfgInitialize(&dev->Iic, &xiic_cfg, xiic_cfg.BaseAddress) !=
	    XST_SUCCESS) {
		up(&cfg_sem);
		dev_err(device, "could not initialize device.\n");
		error = -ENODEV;
		goto out;
	}
	up(&cfg_sem);
	XIic_SetRecvHandler(&dev->Iic, (void *)dev, RecvHandler);
	XIic_SetSendHandler(&dev->Iic, (void *)dev, SendHandler);
	XIic_SetStatusHandler(&dev->Iic, (void *)dev, StatusHandler);

	/* Grab the IRQ */
	error = request_irq(dev->irq, xiic_interrupt, 0, dev->adap.name, dev);
	if (error) {
		dev_err(device, "could not allocate interrupt %d.\n", dev->irq);
		goto out;
	}
	dev->reqirq = 1;

	if (XIic_Start(&dev->Iic) != XST_SUCCESS) {
		dev_err(device, "could not start device\n");
		error = -ENODEV;
		goto out;
	}
	dev->started = 1;

	/* Now tell the core I2C code about our new device. */

	strcpy(dev->adap.name, "xilinx-iic");
	dev->adap.dev.of_node = node;
	dev->adap.algo = &xiic_algo;
	dev->adap.algo_data = NULL;
	dev->adap.timeout = XIIC_TIMEOUT;
	dev->adap.retries = XIIC_RETRY;
	error = i2c_add_adapter(&dev->adap);

	if (error) {
		dev_err(device, "could not add i2c adapter\n");
		goto out;
	}
	dev->added = 1;

	printk("%s #%d at 0x%08X mapped to 0x%08X, irq=%d\n",
	       dev->adap.name, dev->index,
	       dev->base, (unsigned int)dev->Iic.BaseAddress, dev->irq);

	if (scan) {
		scan_results = xilinx_iic_do_scan(dev);
		if (scan_results) {
			printk(scan_results);
			kfree(scan_results);
		}
	}
	
	of_i2c_register_devices(&dev->adap);

	error = device_create_file(device, &dev_attr_scan);
      out:
	if (error)
		xilinx_iic_remove(device);
      out2:
	return error;
}
Ejemplo n.º 3
0
static int octeon_i2c_probe(struct platform_device *pdev)
{
	int irq, result = 0;
	struct octeon_i2c *i2c;
	struct resource *res_mem;

	/* All adaptors have an irq.  */
	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return irq;

	i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
	if (!i2c) {
		dev_err(&pdev->dev, "kzalloc failed\n");
		result = -ENOMEM;
		goto out;
	}
	i2c->dev = &pdev->dev;

	res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);

	if (res_mem == NULL) {
		dev_err(i2c->dev, "found no memory resource\n");
		result = -ENXIO;
		goto out;
	}
	i2c->twsi_phys = res_mem->start;
	i2c->regsize = resource_size(res_mem);

	/*
	 * "clock-rate" is a legacy binding, the official binding is
	 * "clock-frequency".  Try the official one first and then
	 * fall back if it doesn't exist.
	 */
	if (of_property_read_u32(pdev->dev.of_node,
				 "clock-frequency", &i2c->twsi_freq) &&
	    of_property_read_u32(pdev->dev.of_node,
				 "clock-rate", &i2c->twsi_freq)) {
		dev_err(i2c->dev,
			"no I2C 'clock-rate' or 'clock-frequency' property\n");
		result = -ENXIO;
		goto out;
	}

	i2c->sys_freq = octeon_get_io_clock_rate();

	if (!devm_request_mem_region(&pdev->dev, i2c->twsi_phys, i2c->regsize,
				      res_mem->name)) {
		dev_err(i2c->dev, "request_mem_region failed\n");
		goto out;
	}
	i2c->twsi_base = devm_ioremap(&pdev->dev, i2c->twsi_phys, i2c->regsize);

	init_waitqueue_head(&i2c->queue);

	i2c->irq = irq;

	result = devm_request_irq(&pdev->dev, i2c->irq,
				  octeon_i2c_isr, 0, DRV_NAME, i2c);
	if (result < 0) {
		dev_err(i2c->dev, "failed to attach interrupt\n");
		goto out;
	}

	result = octeon_i2c_initlowlevel(i2c);
	if (result) {
		dev_err(i2c->dev, "init low level failed\n");
		goto  out;
	}

	result = octeon_i2c_setclock(i2c);
	if (result) {
		dev_err(i2c->dev, "clock init failed\n");
		goto  out;
	}

	i2c->adap = octeon_i2c_ops;
	i2c->adap.dev.parent = &pdev->dev;
	i2c->adap.dev.of_node = pdev->dev.of_node;
	i2c_set_adapdata(&i2c->adap, i2c);
	platform_set_drvdata(pdev, i2c);

	result = i2c_add_adapter(&i2c->adap);
	if (result < 0) {
		dev_err(i2c->dev, "failed to add adapter\n");
		goto fail_add;
	}
	dev_info(i2c->dev, "version %s\n", DRV_VERSION);

	of_i2c_register_devices(&i2c->adap);

	return 0;

fail_add:
	platform_set_drvdata(pdev, NULL);
out:
	return result;
};
Ejemplo n.º 4
0
static int xiic_i2c_probe(struct platform_device *pdev)
{
	struct xiic_i2c *i2c;
	struct xiic_i2c_platform_data *pdata;
	struct resource *res;
	int ret, irq;
	u8 i;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res)
		goto resource_missing;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		goto resource_missing;

	pdata = (struct xiic_i2c_platform_data *) pdev->dev.platform_data;

	i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
	if (!i2c)
		return -ENOMEM;

	if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
		dev_err(&pdev->dev, "Memory region busy\n");
		ret = -EBUSY;
		goto request_mem_failed;
	}

	i2c->base = ioremap(res->start, resource_size(res));
	if (!i2c->base) {
		dev_err(&pdev->dev, "Unable to map registers\n");
		ret = -EIO;
		goto map_failed;
	}

	/* hook up driver to tree */
	platform_set_drvdata(pdev, i2c);
	i2c->adap = xiic_adapter;
	i2c_set_adapdata(&i2c->adap, i2c);
	i2c->adap.dev.parent = &pdev->dev;
	i2c->adap.dev.of_node = pdev->dev.of_node;

	xiic_reinit(i2c);

	spin_lock_init(&i2c->lock);
	init_waitqueue_head(&i2c->wait);
	ret = request_irq(irq, xiic_isr, 0, pdev->name, i2c);
	if (ret) {
		dev_err(&pdev->dev, "Cannot claim IRQ\n");
		goto request_irq_failed;
	}

	/* add i2c adapter to i2c tree */
	ret = i2c_add_adapter(&i2c->adap);
	if (ret) {
		dev_err(&pdev->dev, "Failed to add adapter\n");
		goto add_adapter_failed;
	}

	if (pdata) {
		/* add in known devices to the bus */
		for (i = 0; i < pdata->num_devices; i++)
			i2c_new_device(&i2c->adap, pdata->devices + i);
	}

	of_i2c_register_devices(&i2c->adap);

	return 0;

add_adapter_failed:
	free_irq(irq, i2c);
request_irq_failed:
	xiic_deinit(i2c);
	iounmap(i2c->base);
map_failed:
	release_mem_region(res->start, resource_size(res));
request_mem_failed:
	kfree(i2c);

	return ret;
resource_missing:
	dev_err(&pdev->dev, "IRQ or Memory resource is missing\n");
	return -ENOENT;
}
Ejemplo n.º 5
0
static int __devinit i2c_pnx_probe(struct platform_device *pdev)
{
	unsigned long tmp;
	int ret = 0;
	struct i2c_pnx_algo_data *alg_data;
	unsigned long freq;
	struct resource *res;
	u32 speed = I2C_PNX_SPEED_KHZ_DEFAULT * 1000;

	alg_data = kzalloc(sizeof(*alg_data), GFP_KERNEL);
	if (!alg_data) {
		ret = -ENOMEM;
		goto err_kzalloc;
	}

	platform_set_drvdata(pdev, alg_data);

	alg_data->adapter.dev.parent = &pdev->dev;
	alg_data->adapter.algo = &pnx_algorithm;
	alg_data->adapter.algo_data = alg_data;
	alg_data->adapter.nr = pdev->id;

	alg_data->timeout = I2C_PNX_TIMEOUT_DEFAULT;
#ifdef CONFIG_OF
	alg_data->adapter.dev.of_node = of_node_get(pdev->dev.of_node);
	if (pdev->dev.of_node) {
		of_property_read_u32(pdev->dev.of_node, "clock-frequency",
				     &speed);
		/*
		 * At this point, it is planned to add an OF timeout property.
		 * As soon as there is a consensus about how to call and handle
		 * this, sth. like the following can be put here:
		 *
		 * of_property_read_u32(pdev->dev.of_node, "timeout",
		 *                      &alg_data->timeout);
		 */
	}
#endif
	alg_data->clk = clk_get(&pdev->dev, NULL);
	if (IS_ERR(alg_data->clk)) {
		ret = PTR_ERR(alg_data->clk);
		goto out_drvdata;
	}

	init_timer(&alg_data->mif.timer);
	alg_data->mif.timer.function = i2c_pnx_timeout;
	alg_data->mif.timer.data = (unsigned long)alg_data;

	snprintf(alg_data->adapter.name, sizeof(alg_data->adapter.name),
		 "%s", pdev->name);

	/* Register I/O resource */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "Unable to get mem resource.\n");
		ret = -EBUSY;
		goto out_clkget;
	}
	if (!request_mem_region(res->start, I2C_PNX_REGION_SIZE,
				pdev->name)) {
		dev_err(&pdev->dev,
		       "I/O region 0x%08x for I2C already in use.\n",
		       res->start);
		ret = -ENOMEM;
		goto out_clkget;
	}

	alg_data->base = res->start;
	alg_data->ioaddr = ioremap(res->start, I2C_PNX_REGION_SIZE);
	if (!alg_data->ioaddr) {
		dev_err(&pdev->dev, "Couldn't ioremap I2C I/O region\n");
		ret = -ENOMEM;
		goto out_release;
	}

	ret = clk_enable(alg_data->clk);
	if (ret)
		goto out_unmap;

	freq = clk_get_rate(alg_data->clk);

	/*
	 * Clock Divisor High This value is the number of system clocks
	 * the serial clock (SCL) will be high.
	 * For example, if the system clock period is 50 ns and the maximum
	 * desired serial period is 10000 ns (100 kHz), then CLKHI would be
	 * set to 0.5*(f_sys/f_i2c)-2=0.5*(20e6/100e3)-2=98. The actual value
	 * programmed into CLKHI will vary from this slightly due to
	 * variations in the output pad's rise and fall times as well as
	 * the deglitching filter length.
	 */

	tmp = (freq / speed) / 2 - 2;
	if (tmp > 0x3FF)
		tmp = 0x3FF;
	iowrite32(tmp, I2C_REG_CKH(alg_data));
	iowrite32(tmp, I2C_REG_CKL(alg_data));

	iowrite32(mcntrl_reset, I2C_REG_CTL(alg_data));
	if (wait_reset(alg_data)) {
		ret = -ENODEV;
		goto out_clock;
	}
	init_completion(&alg_data->mif.complete);

	alg_data->irq = platform_get_irq(pdev, 0);
	if (alg_data->irq < 0) {
		dev_err(&pdev->dev, "Failed to get IRQ from platform resource\n");
		goto out_irq;
	}
	ret = request_irq(alg_data->irq, i2c_pnx_interrupt,
			0, pdev->name, alg_data);
	if (ret)
		goto out_clock;

	/* Register this adapter with the I2C subsystem */
	ret = i2c_add_numbered_adapter(&alg_data->adapter);
	if (ret < 0) {
		dev_err(&pdev->dev, "I2C: Failed to add bus\n");
		goto out_irq;
	}

	of_i2c_register_devices(&alg_data->adapter);

	dev_dbg(&pdev->dev, "%s: Master at %#8x, irq %d.\n",
		alg_data->adapter.name, res->start, alg_data->irq);

	return 0;

out_irq:
	free_irq(alg_data->irq, alg_data);
out_clock:
	clk_disable(alg_data->clk);
out_unmap:
	iounmap(alg_data->ioaddr);
out_release:
	release_mem_region(res->start, I2C_PNX_REGION_SIZE);
out_clkget:
	clk_put(alg_data->clk);
out_drvdata:
	kfree(alg_data);
err_kzalloc:
	platform_set_drvdata(pdev, NULL);
	return ret;
}