示例#1
0
static int __devexit xilinx_iic_of_remove(struct platform_device *ofdev)
{
	return xilinx_iic_remove(&ofdev->dev);
}
示例#2
0
static int __init xilinx_iic_probe(struct of_device *of_dev,
				   const struct of_device_id *match)
{
	XIic_Config xiic_cfg;
	struct xiic_data *dev;
	char *scan_results;
	struct resource mem;
	struct device_node *dev_node = of_dev->node;
	int error;
	const u32 *did;

	/* Allocate the dev and zero it out. */
	dev = kzalloc(sizeof(struct xiic_data), SLAB_KERNEL);
	if (!dev) {
		dev_err(&of_dev->dev, "Cannot allocate struct xiic_data\n");
		error = -ENOMEM;
		goto out2;
	}

	dev_set_drvdata(&of_dev->dev, dev);

	/* get resources from device tree */
	dev->irq = irq_of_parse_and_map(dev_node, 0);
	if (dev->irq == 0 /* NOIRQ */ ) {
		error = -ENODEV;
		goto out;
	}

	if (of_address_to_resource(dev_node, 0, &mem)) {
		error = -ENODEV;
		goto out;
	}

	/* initialize fields to satisfy i2c  */
	strcpy(dev->adap.name, of_dev->dev.bus_id);

	did = of_get_property(dev_node, "index", NULL);
	if (did == NULL) {
		printk
		    ("%s: Can not get device index from device tree, assume 0\n",
		     __FUNCTION__);
		dev->index = 0;
	} else
		dev->index = *did;

	init_completion(&dev->complete);

	memset(&xiic_cfg, 0, sizeof(XIic_Config));
	xiic_cfg.DeviceId = dev->index;

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

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

	/* 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(&of_dev->dev, "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(&of_dev->dev, "could not allocate interrupt %d.\n",
			dev->irq);
		goto out;
	}
	dev->reqirq = 1;

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

	/* Now tell the core I2C code about our new device. */
	/*
	 * SAATODO: Get a real ID (perhaps I2C_HW_XILINX) after
	 * initial release.  Will need to email [email protected]
	 * per http://www2.lm-sensors.nu/~lm78/support.html
	 */
	dev->adap.id = I2C_DRIVERID_I2CDEV;
	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(&of_dev->dev, "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, dev->Iic.BaseAddress, dev->irq);

	if (scan) {
		scan_results = xilinx_iic_do_scan(dev);
		if (scan_results) {
			printk(scan_results);
			kfree(scan_results);
		}
	}

	device_create_file(&of_dev->dev, &dev_attr_scan);
      out:
	if (error)
		xilinx_iic_remove(of_dev);
      out2:
	return error;
}
示例#3
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;
}
示例#4
0
static int __init xilinx_iic_probe(struct device *device)
{
	XIic_Config xiic_cfg;
	struct platform_device *pdev = to_platform_device(device);
	struct xiic_data *dev;
	char *scan_results;
	struct resource *mem;
	int error;

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

	dev_set_drvdata(device, dev);

	/* get resources from resource list of passed platform_device */
	dev->irq = platform_get_irq(pdev, 0);
	if (dev->irq == 0 /* NOIRQ */ ) {
		error = -ENODEV;
		goto out;
	}
	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!mem) {
		error = -ENODEV;
		goto out;
	}

	/* initialize fields to satisfy i2c  */
	strcpy(dev->adap.name, device->bus_id);
	dev->index = pdev->id;

	init_completion(&dev->complete);

	memset(&xiic_cfg, 0, sizeof(XIic_Config));
	xiic_cfg.DeviceId = pdev->id;

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

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

	/* 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. */
	/*
	 * SAATODO: Get a real ID (perhaps I2C_HW_XILINX) after
	 * initial release.  Will need to email [email protected]
	 * per http://www2.lm-sensors.nu/~lm78/support.html
	 */
	dev->adap.id = xiic_algo.id | I2C_DRIVERID_EXP0;
	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, dev->Iic.BaseAddress, dev->irq);

	if (scan) {
		scan_results = xilinx_iic_do_scan(dev);
		if (scan_results) {
			printk(scan_results);
			kfree(scan_results);
		}
	}

	device_create_file(device, &dev_attr_scan);
      out:
	if (error)
		xilinx_iic_remove(device);
      out2:
	return error;
}