static int __init amd756_s4882_init(void)
{
	int i, error;
	union i2c_smbus_data ioconfig;

	if (!amd756_smbus.dev.parent)
		return -ENODEV;

	
	ioconfig.byte = 0x00; 
	error = i2c_smbus_xfer(&amd756_smbus, 0x18, 0, I2C_SMBUS_WRITE, 0x03,
			       I2C_SMBUS_BYTE_DATA, &ioconfig);
	if (error) {
		dev_err(&amd756_smbus.dev, "PCA9556 configuration failed\n");
		error = -EIO;
		goto ERROR0;
	}

	
	error = i2c_del_adapter(&amd756_smbus);
	if (error) {
		dev_err(&amd756_smbus.dev, "Physical bus removal failed\n");
		goto ERROR0;
	}

	printk(KERN_INFO "Enabling SMBus multiplexing for Tyan S4882\n");
	
	if (!(s4882_adapter = kzalloc(5 * sizeof(struct i2c_adapter),
				      GFP_KERNEL))) {
		error = -ENOMEM;
		goto ERROR1;
	}
	if (!(s4882_algo = kzalloc(5 * sizeof(struct i2c_algorithm),
				   GFP_KERNEL))) {
		error = -ENOMEM;
		goto ERROR2;
	}

	
	s4882_algo[0] = *(amd756_smbus.algo);
	s4882_algo[0].smbus_xfer = amd756_access_virt0;
	s4882_adapter[0] = amd756_smbus;
	s4882_adapter[0].algo = s4882_algo;
	s4882_adapter[0].dev.parent = amd756_smbus.dev.parent;
	for (i = 1; i < 5; i++) {
		s4882_algo[i] = *(amd756_smbus.algo);
		s4882_adapter[i] = amd756_smbus;
		snprintf(s4882_adapter[i].name, sizeof(s4882_adapter[i].name),
			 "SMBus 8111 adapter (CPU%d)", i-1);
		s4882_adapter[i].algo = s4882_algo+i;
		s4882_adapter[i].dev.parent = amd756_smbus.dev.parent;
	}
	s4882_algo[1].smbus_xfer = amd756_access_virt1;
	s4882_algo[2].smbus_xfer = amd756_access_virt2;
	s4882_algo[3].smbus_xfer = amd756_access_virt3;
	s4882_algo[4].smbus_xfer = amd756_access_virt4;

	
	for (i = 0; i < 5; i++) {
		error = i2c_add_adapter(s4882_adapter+i);
		if (error) {
			printk(KERN_ERR "i2c-amd756-s4882: "
			       "Virtual adapter %d registration "
			       "failed, module not inserted\n", i);
			for (i--; i >= 0; i--)
				i2c_del_adapter(s4882_adapter+i);
			goto ERROR3;
		}
	}

	return 0;

ERROR3:
	kfree(s4882_algo);
	s4882_algo = NULL;
ERROR2:
	kfree(s4882_adapter);
	s4882_adapter = NULL;
ERROR1:
	
	i2c_add_adapter(&amd756_smbus);
ERROR0:
	return error;
}
Esempio n. 2
0
static int owl_i2c_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct owl_i2c_dev *i2c_dev;
	struct resource *res;
	int ret, irq;

	i2c_dev = devm_kzalloc(dev, sizeof(*i2c_dev), GFP_KERNEL);
	if (!i2c_dev)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	i2c_dev->base = devm_ioremap_resource(dev, res);
	if (IS_ERR(i2c_dev->base))
		return PTR_ERR(i2c_dev->base);

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		dev_err(dev, "failed to get IRQ number\n");
		return irq;
	}

	if (of_property_read_u32(dev->of_node, "clock-frequency",
				 &i2c_dev->bus_freq))
		i2c_dev->bus_freq = OWL_I2C_DEF_SPEED_HZ;

	/* We support only frequencies of 100k and 400k for now */
	if (i2c_dev->bus_freq != OWL_I2C_DEF_SPEED_HZ &&
	    i2c_dev->bus_freq != OWL_I2C_MAX_SPEED_HZ) {
		dev_err(dev, "invalid clock-frequency %d\n", i2c_dev->bus_freq);
		return -EINVAL;
	}

	i2c_dev->clk = devm_clk_get(dev, NULL);
	if (IS_ERR(i2c_dev->clk)) {
		dev_err(dev, "failed to get clock\n");
		return PTR_ERR(i2c_dev->clk);
	}

	ret = clk_prepare_enable(i2c_dev->clk);
	if (ret)
		return ret;

	i2c_dev->clk_rate = clk_get_rate(i2c_dev->clk);
	if (!i2c_dev->clk_rate) {
		dev_err(dev, "input clock rate should not be zero\n");
		ret = -EINVAL;
		goto disable_clk;
	}

	init_completion(&i2c_dev->msg_complete);
	spin_lock_init(&i2c_dev->lock);
	i2c_dev->adap.owner = THIS_MODULE;
	i2c_dev->adap.algo = &owl_i2c_algorithm;
	i2c_dev->adap.timeout = OWL_I2C_TIMEOUT;
	i2c_dev->adap.quirks = &owl_i2c_quirks;
	i2c_dev->adap.dev.parent = dev;
	i2c_dev->adap.dev.of_node = dev->of_node;
	snprintf(i2c_dev->adap.name, sizeof(i2c_dev->adap.name),
		 "%s", "OWL I2C adapter");
	i2c_set_adapdata(&i2c_dev->adap, i2c_dev);

	platform_set_drvdata(pdev, i2c_dev);

	ret = devm_request_irq(dev, irq, owl_i2c_interrupt, 0, pdev->name,
			       i2c_dev);
	if (ret) {
		dev_err(dev, "failed to request irq %d\n", irq);
		goto disable_clk;
	}

	return i2c_add_adapter(&i2c_dev->adap);

disable_clk:
	clk_disable_unprepare(i2c_dev->clk);

	return ret;
}
Esempio n. 3
0
static int __devinit amd756_probe(struct pci_dev *pdev,
				  const struct pci_device_id *id)
{
	int nforce = (id->driver_data == NFORCE);
	int error;
	u8 temp;
	
	if (amd756_ioport) {
		dev_err(&pdev->dev, ": Only one device supported. "
		       "(you have a strange motherboard, btw..)\n");
		return -ENODEV;
	}

	if (nforce) {
		if (PCI_FUNC(pdev->devfn) != 1)
			return -ENODEV;

		pci_read_config_word(pdev, SMBBANFORCE, &amd756_ioport);
		amd756_ioport &= 0xfffc;
	} else { /* amd */
		if (PCI_FUNC(pdev->devfn) != 3)
			return -ENODEV;

		pci_read_config_byte(pdev, SMBGCFG, &temp);
		if ((temp & 128) == 0) {
			dev_err(&pdev->dev,
				": Error: SMBus controller I/O not enabled!\n");
			return -ENODEV;
		}

		/* Determine the address of the SMBus areas */
		/* Technically it is a dword but... */
		pci_read_config_word(pdev, SMBBA, &amd756_ioport);
		amd756_ioport &= 0xff00;
		amd756_ioport += SMB_ADDR_OFFSET;
	}

	if (!request_region(amd756_ioport, SMB_IOSIZE, "amd756-smbus")) {
		dev_err(&pdev->dev, ": SMB region 0x%x already in use!\n",
			amd756_ioport);
		return -ENODEV;
	}

	pci_read_config_byte(pdev, SMBREV, &temp);
	dev_dbg(&pdev->dev, ": SMBREV = 0x%X\n", temp);
	dev_dbg(&pdev->dev, ": AMD756_smba = 0x%X\n", amd756_ioport);

	/* set up the driverfs linkage to our parent device */
	amd756_adapter.dev.parent = &pdev->dev;

	snprintf(amd756_adapter.name, I2C_NAME_SIZE,
		"SMBus AMD756 adapter at %04x", amd756_ioport);

	error = i2c_add_adapter(&amd756_adapter);
	if (error) {
		dev_err(&pdev->dev,
			": Adapter registration failed, module not inserted.\n");
		goto out_err;
	}

	return 0;

 out_err:
	release_region(amd756_ioport, SMB_IOSIZE);
	return error;
}
Esempio n. 4
0
/* init + register i2c algo-bit adapter */
int cx23885_i2c_register(struct cx23885_i2c *bus)
{
	struct cx23885_dev *dev = bus->dev;

	dprintk(1, "%s(bus = %d)\n", __func__, bus->nr);

	memcpy(&bus->i2c_adap, &cx23885_i2c_adap_template,
	       sizeof(bus->i2c_adap));
	memcpy(&bus->i2c_algo, &cx23885_i2c_algo_template,
	       sizeof(bus->i2c_algo));
	memcpy(&bus->i2c_client, &cx23885_i2c_client_template,
	       sizeof(bus->i2c_client));

	bus->i2c_adap.dev.parent = &dev->pci->dev;

	strlcpy(bus->i2c_adap.name, bus->dev->name,
		sizeof(bus->i2c_adap.name));

	bus->i2c_algo.data = bus;
	bus->i2c_adap.algo_data = bus;
	i2c_set_adapdata(&bus->i2c_adap, &dev->v4l2_dev);
	i2c_add_adapter(&bus->i2c_adap);

	bus->i2c_client.adapter = &bus->i2c_adap;

	if (0 == bus->i2c_rc) {
		dprintk(1, "%s: i2c bus %d registered\n", dev->name, bus->nr);
		if (i2c_scan) {
			printk(KERN_INFO "%s: scan bus %d:\n",
					dev->name, bus->nr);
			do_i2c_scan(dev->name, &bus->i2c_client);
		}
	} else
		printk(KERN_WARNING "%s: i2c bus %d register FAILED\n",
			dev->name, bus->nr);

	/* Instantiate the IR receiver device, if present */
	if (0 == bus->i2c_rc) {
		struct i2c_board_info info;
		const unsigned short addr_list[] = {
			0x6b, I2C_CLIENT_END
		};

		memset(&info, 0, sizeof(struct i2c_board_info));
		strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
		/* Use quick read command for probe, some IR chips don't
		 * support writes */
		i2c_new_probed_device(&bus->i2c_adap, &info, addr_list,
				      i2c_probe_func_quick_read);
#else
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)			 
		/*
		 * We can't call i2c_new_probed_device() because it uses
		 * quick writes for probing and the IR receiver device only
		 * replies to reads.
		 */
		if (i2c_smbus_xfer(&bus->i2c_adap, addr_list[0], 0,
				   I2C_SMBUS_READ, 0, I2C_SMBUS_QUICK,
				   NULL) >= 0) {
			info.addr = addr_list[0];
			i2c_new_device(&bus->i2c_adap, &info);
		}
#endif
#endif
	}

	return bus->i2c_rc;
}
Esempio n. 5
0
static int  __init scx200_acb_create(int base, int index)
{
	struct scx200_acb_iface *iface;
	struct i2c_adapter *adapter;
	int rc = 0;

	iface = kmalloc(sizeof(*iface), GFP_KERNEL);
	if (!iface) {
		printk(KERN_ERR NAME ": can't allocate memory\n");
		rc = -ENOMEM;
		goto errout;
	}

	memset(iface, 0, sizeof(*iface));
	adapter = &iface->adapter;
	adapter->data = iface;
	sprintf(adapter->name, "SCx200 ACB%d", index);
	adapter->id = I2C_ALGO_SMBUS;
	adapter->algo = &scx200_acb_algorithm;
	adapter->inc_use = scx200_acb_inc_use;
	adapter->dec_use = scx200_acb_dec_use;
	adapter->client_register = scx200_acb_reg;
	adapter->client_unregister = scx200_acb_unreg;

	init_MUTEX(&iface->sem);

	if (request_region(base, 8, adapter->name) == 0) {
		printk(KERN_ERR NAME ": %s, can't allocate io 0x%x-0x%x\n", 
		       adapter->name, base, base + 8-1);
		rc = -EBUSY;
		goto errout;
	}
	iface->base = base;

	rc = scx200_acb_probe(iface);
	if (rc) {
		printk(KERN_WARNING NAME ": %s, probe failed\n", adapter->name);
		goto errout;
	}

	scx200_acb_reset(iface);

	if (i2c_add_adapter(adapter) < 0) {
		printk(KERN_ERR NAME ": %s, failed to register\n", adapter->name);
		rc = -ENODEV;
		goto errout;
	}

	lock_kernel();
	iface->next = scx200_acb_list;
	scx200_acb_list = iface;
	unlock_kernel();

	return 0;

 errout:
	if (iface) {
		if (iface->base)
			release_region(iface->base, 8);
		kfree(iface);
	}
	return rc;
}
Esempio n. 6
0
int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
		      struct saa7146_pci_extension_data *info,
		      struct module *owner, short *adapter_nums)
{
	int ret = 0;
	struct budget_info *bi = info->ext_priv;
	int max_bufsize;
	int height_mask;

	memset(budget, 0, sizeof(struct budget));

	dprintk(2, "dev: %p, budget: %p\n", dev, budget);

	budget->card = bi;
	budget->dev = (struct saa7146_dev *) dev;

	switch(budget->card->type) {
	case BUDGET_FS_ACTIVY:
		budget->buffer_width = TS_WIDTH_ACTIVY;
		max_bufsize = TS_MAX_BUFSIZE_K_ACTIVY;
		height_mask = TS_HEIGHT_MASK_ACTIVY;
		break;

	case BUDGET_KNC1C:
	case BUDGET_KNC1CP:
	case BUDGET_CIN1200C:
	case BUDGET_KNC1C_MK3:
	case BUDGET_KNC1C_TDA10024:
	case BUDGET_KNC1CP_MK3:
	case BUDGET_CIN1200C_MK3:
		budget->buffer_width = TS_WIDTH_DVBC;
		max_bufsize = TS_MAX_BUFSIZE_K_DVBC;
		height_mask = TS_HEIGHT_MASK_DVBC;
		break;

	default:
		budget->buffer_width = TS_WIDTH;
		max_bufsize = TS_MAX_BUFSIZE_K;
		height_mask = TS_HEIGHT_MASK;
	}

	if (dma_buffer_size < TS_MIN_BUFSIZE_K)
		dma_buffer_size = TS_MIN_BUFSIZE_K;
	else if (dma_buffer_size > max_bufsize)
		dma_buffer_size = max_bufsize;

	budget->buffer_height = dma_buffer_size * 1024 / budget->buffer_width;
	if (budget->buffer_height > 0xfff) {
		budget->buffer_height /= 2;
		budget->buffer_height &= height_mask;
		budget->buffer_size = 2 * budget->buffer_height * budget->buffer_width;
	} else {
		budget->buffer_height &= height_mask;
		budget->buffer_size = budget->buffer_height * budget->buffer_width;
	}
	budget->buffer_warning_threshold = budget->buffer_size * 80/100;
	budget->buffer_warnings = 0;
	budget->buffer_warning_time = jiffies;

	dprintk(2, "%s: buffer type = %s, width = %d, height = %d\n",
		budget->dev->name,
		budget->buffer_size > budget->buffer_width * budget->buffer_height ? "odd/even" : "single",
		budget->buffer_width, budget->buffer_height);
	printk("%s: dma buffer size %u\n", budget->dev->name, budget->buffer_size);

	ret = dvb_register_adapter(&budget->dvb_adapter, budget->card->name,
				   owner, &budget->dev->pci->dev, adapter_nums);
	if (ret < 0)
		return ret;

	/* set dd1 stream a & b */
	saa7146_write(dev, DD1_STREAM_B, 0x00000000);
	saa7146_write(dev, MC2, (MASK_09 | MASK_25));
	saa7146_write(dev, MC2, (MASK_10 | MASK_26));
	saa7146_write(dev, DD1_INIT, 0x02000000);
	saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));

	if (bi->type != BUDGET_FS_ACTIVY)
		budget->video_port = BUDGET_VIDEO_PORTB;
	else
		budget->video_port = BUDGET_VIDEO_PORTA;
	spin_lock_init(&budget->feedlock);
	spin_lock_init(&budget->debilock);

	/* the Siemens DVB needs this if you want to have the i2c chips
	   get recognized before the main driver is loaded */
	if (bi->type != BUDGET_FS_ACTIVY)
		saa7146_write(dev, GPIO_CTRL, 0x500000);	/* GPIO 3 = 1 */

	strscpy(budget->i2c_adap.name, budget->card->name,
		sizeof(budget->i2c_adap.name));

	saa7146_i2c_adapter_prepare(dev, &budget->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120);
	strscpy(budget->i2c_adap.name, budget->card->name,
		sizeof(budget->i2c_adap.name));

	if (i2c_add_adapter(&budget->i2c_adap) < 0) {
		ret = -ENOMEM;
		goto err_dvb_unregister;
	}

	ttpci_eeprom_parse_mac(&budget->i2c_adap, budget->dvb_adapter.proposed_mac);

	budget->grabbing = saa7146_vmalloc_build_pgtable(dev->pci, budget->buffer_size, &budget->pt);
	if (NULL == budget->grabbing) {
		ret = -ENOMEM;
		goto err_del_i2c;
	}

	saa7146_write(dev, PCI_BT_V1, 0x001c0000);
	/* upload all */
	saa7146_write(dev, GPIO_CTRL, 0x000000);

	tasklet_init(&budget->vpe_tasklet, vpeirq, (unsigned long) budget);

	/* frontend power on */
	if (bi->type != BUDGET_FS_ACTIVY)
		saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI);

	if ((ret = budget_register(budget)) == 0)
		return 0; /* Everything OK */

	/* An error occurred, cleanup resources */
	saa7146_vfree_destroy_pgtable(dev->pci, budget->grabbing, &budget->pt);

err_del_i2c:
	i2c_del_adapter(&budget->i2c_adap);

err_dvb_unregister:
	dvb_unregister_adapter(&budget->dvb_adapter);

	return ret;
}
Esempio n. 7
0
/*
 * registering functions to load algorithms at runtime
 */
int i2c_sgi_add_bus(struct i2c_adapter *adap)
{
    adap->algo = &sgi_algo;

    return i2c_add_adapter(adap);
}
Esempio n. 8
0
static int p2wi_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	struct device_node *childnp;
	unsigned long parent_clk_freq;
	u32 clk_freq = 100000;
	struct resource *r;
	struct p2wi *p2wi;
	u32 slave_addr;
	int clk_div;
	int irq;
	int ret;

	of_property_read_u32(np, "clock-frequency", &clk_freq);
	if (clk_freq > P2WI_MAX_FREQ) {
		dev_err(dev,
			"required clock-frequency (%u Hz) is too high (max = 6MHz)",
			clk_freq);
		return -EINVAL;
	}

	if (of_get_child_count(np) > 1) {
		dev_err(dev, "P2WI only supports one slave device\n");
		return -EINVAL;
	}

	p2wi = devm_kzalloc(dev, sizeof(struct p2wi), GFP_KERNEL);
	if (!p2wi)
		return -ENOMEM;

	p2wi->slave_addr = -1;

	/*
	 * Authorize a p2wi node without any children to be able to use an
	 * i2c-dev from userpace.
	 * In this case the slave_addr is set to -1 and won't be checked when
	 * launching a P2WI transfer.
	 */
	childnp = of_get_next_available_child(np, NULL);
	if (childnp) {
		ret = of_property_read_u32(childnp, "reg", &slave_addr);
		if (ret) {
			dev_err(dev, "invalid slave address on node %pOF\n",
				childnp);
			return -EINVAL;
		}

		p2wi->slave_addr = slave_addr;
	}

	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	p2wi->regs = devm_ioremap_resource(dev, r);
	if (IS_ERR(p2wi->regs))
		return PTR_ERR(p2wi->regs);

	strlcpy(p2wi->adapter.name, pdev->name, sizeof(p2wi->adapter.name));
	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		dev_err(dev, "failed to retrieve irq: %d\n", irq);
		return irq;
	}

	p2wi->clk = devm_clk_get(dev, NULL);
	if (IS_ERR(p2wi->clk)) {
		ret = PTR_ERR(p2wi->clk);
		dev_err(dev, "failed to retrieve clk: %d\n", ret);
		return ret;
	}

	ret = clk_prepare_enable(p2wi->clk);
	if (ret) {
		dev_err(dev, "failed to enable clk: %d\n", ret);
		return ret;
	}

	parent_clk_freq = clk_get_rate(p2wi->clk);

	p2wi->rstc = devm_reset_control_get_exclusive(dev, NULL);
	if (IS_ERR(p2wi->rstc)) {
		ret = PTR_ERR(p2wi->rstc);
		dev_err(dev, "failed to retrieve reset controller: %d\n", ret);
		goto err_clk_disable;
	}

	ret = reset_control_deassert(p2wi->rstc);
	if (ret) {
		dev_err(dev, "failed to deassert reset line: %d\n", ret);
		goto err_clk_disable;
	}

	init_completion(&p2wi->complete);
	p2wi->adapter.dev.parent = dev;
	p2wi->adapter.algo = &p2wi_algo;
	p2wi->adapter.owner = THIS_MODULE;
	p2wi->adapter.dev.of_node = pdev->dev.of_node;
	platform_set_drvdata(pdev, p2wi);
	i2c_set_adapdata(&p2wi->adapter, p2wi);

	ret = devm_request_irq(dev, irq, p2wi_interrupt, 0, pdev->name, p2wi);
	if (ret) {
		dev_err(dev, "can't register interrupt handler irq%d: %d\n",
			irq, ret);
		goto err_reset_assert;
	}

	writel(P2WI_CTRL_SOFT_RST, p2wi->regs + P2WI_CTRL);

	clk_div = parent_clk_freq / clk_freq;
	if (!clk_div) {
		dev_warn(dev,
			 "clock-frequency is too high, setting it to %lu Hz\n",
			 parent_clk_freq);
		clk_div = 1;
	} else if (clk_div > P2WI_CCR_MAX_CLK_DIV) {
		dev_warn(dev,
			 "clock-frequency is too low, setting it to %lu Hz\n",
			 parent_clk_freq / P2WI_CCR_MAX_CLK_DIV);
		clk_div = P2WI_CCR_MAX_CLK_DIV;
	}

	writel(P2WI_CCR_SDA_OUT_DELAY(1) | P2WI_CCR_CLK_DIV(clk_div),
	       p2wi->regs + P2WI_CCR);

	ret = i2c_add_adapter(&p2wi->adapter);
	if (!ret)
		return 0;

err_reset_assert:
	reset_control_assert(p2wi->rstc);

err_clk_disable:
	clk_disable_unprepare(p2wi->clk);

	return ret;
}
Esempio n. 9
0
static int __init nforce2_s4985_init(void)
{
	int i, error;
	union i2c_smbus_data ioconfig;

	if (!nforce2_smbus)
		return -ENODEV;

	/* Configure the PCA9556 multiplexer */
	ioconfig.byte = 0x00; /* All I/O to output mode */
	error = i2c_smbus_xfer(nforce2_smbus, 0x18, 0, I2C_SMBUS_WRITE, 0x03,
			       I2C_SMBUS_BYTE_DATA, &ioconfig);
	if (error) {
		dev_err(&nforce2_smbus->dev, "PCA9556 configuration failed\n");
		error = -EIO;
		goto ERROR0;
	}

	/* Unregister physical bus */
	i2c_del_adapter(nforce2_smbus);

	printk(KERN_INFO "Enabling SMBus multiplexing for Tyan S4985\n");
	/* Define the 5 virtual adapters and algorithms structures */
	s4985_adapter = kzalloc(5 * sizeof(struct i2c_adapter), GFP_KERNEL);
	if (!s4985_adapter) {
		error = -ENOMEM;
		goto ERROR1;
	}
	s4985_algo = kzalloc(5 * sizeof(struct i2c_algorithm), GFP_KERNEL);
	if (!s4985_algo) {
		error = -ENOMEM;
		goto ERROR2;
	}

	/* Fill in the new structures */
	s4985_algo[0] = *(nforce2_smbus->algo);
	s4985_algo[0].smbus_xfer = nforce2_access_virt0;
	s4985_adapter[0] = *nforce2_smbus;
	s4985_adapter[0].algo = s4985_algo;
	s4985_adapter[0].dev.parent = nforce2_smbus->dev.parent;
	for (i = 1; i < 5; i++) {
		s4985_algo[i] = *(nforce2_smbus->algo);
		s4985_adapter[i] = *nforce2_smbus;
		snprintf(s4985_adapter[i].name, sizeof(s4985_adapter[i].name),
			 "SMBus nForce2 adapter (CPU%d)", i - 1);
		s4985_adapter[i].algo = s4985_algo + i;
		s4985_adapter[i].dev.parent = nforce2_smbus->dev.parent;
	}
	s4985_algo[1].smbus_xfer = nforce2_access_virt1;
	s4985_algo[2].smbus_xfer = nforce2_access_virt2;
	s4985_algo[3].smbus_xfer = nforce2_access_virt3;
	s4985_algo[4].smbus_xfer = nforce2_access_virt4;

	/* Register virtual adapters */
	for (i = 0; i < 5; i++) {
		error = i2c_add_adapter(s4985_adapter + i);
		if (error) {
			printk(KERN_ERR "i2c-nforce2-s4985: "
			       "Virtual adapter %d registration "
			       "failed, module not inserted\n", i);
			for (i--; i >= 0; i--)
				i2c_del_adapter(s4985_adapter + i);
			goto ERROR3;
		}
	}

	return 0;

ERROR3:
	kfree(s4985_algo);
	s4985_algo = NULL;
ERROR2:
	kfree(s4985_adapter);
	s4985_adapter = NULL;
ERROR1:
	/* Restore physical bus */
	i2c_add_adapter(nforce2_smbus);
ERROR0:
	return error;
}
Esempio n. 10
0
static int
create_iface(struct device_node *np, struct device *dev)
{
	unsigned long steps;
	unsigned bsteps, tsize, i, nchan, addroffset;
	struct keywest_iface* iface;
	u32 *psteps, *prate;
	int rc;

	if (pmac_low_i2c_lock(np))
		return -ENODEV;

	psteps = (u32 *)get_property(np, "AAPL,address-step", NULL);
	steps = psteps ? (*psteps) : 0x10;

	/* Hrm... maybe we can be smarter here */
	for (bsteps = 0; (steps & 0x01) == 0; bsteps++)
		steps >>= 1;

	if (np->parent->name[0] == 'u') {
		nchan = 2;
		addroffset = 3;
	} else {
		addroffset = 0;
		nchan = 1;
	}

	tsize = sizeof(struct keywest_iface) +
		(sizeof(struct keywest_chan) + 4) * nchan;
	iface = (struct keywest_iface *) kmalloc(tsize, GFP_KERNEL);
	if (iface == NULL) {
		printk(KERN_ERR "i2c-keywest: can't allocate inteface !\n");
		pmac_low_i2c_unlock(np);
		return -ENOMEM;
	}
	memset(iface, 0, tsize);
	spin_lock_init(&iface->lock);
	init_completion(&iface->complete);
	iface->node = of_node_get(np);
	iface->bsteps = bsteps;
	iface->chan_count = nchan;
	iface->state = state_idle;
	iface->irq = np->intrs[0].line;
	iface->channels = (struct keywest_chan *)
		(((unsigned long)(iface + 1) + 3UL) & ~3UL);
	iface->base = ioremap(np->addrs[0].address + addroffset,
						np->addrs[0].size);
	if (!iface->base) {
		printk(KERN_ERR "i2c-keywest: can't map inteface !\n");
		kfree(iface);
		pmac_low_i2c_unlock(np);
		return -ENOMEM;
	}

#ifndef POLLED_MODE
	init_timer(&iface->timeout_timer);
	iface->timeout_timer.function = keywest_timeout;
	iface->timeout_timer.data = (unsigned long)iface;
#endif

	/* Select interface rate */
	iface->cur_mode = KW_I2C_MODE_100KHZ;
	prate = (u32 *)get_property(np, "AAPL,i2c-rate", NULL);
	if (prate) switch(*prate) {
	case 100:
		iface->cur_mode = KW_I2C_MODE_100KHZ;
		break;
	case 50:
		iface->cur_mode = KW_I2C_MODE_50KHZ;
		break;
	case 25:
		iface->cur_mode = KW_I2C_MODE_25KHZ;
		break;
	default:
		printk(KERN_WARNING "i2c-keywest: unknown rate %ldKhz, using 100KHz\n",
		       (long)*prate);
	}
	
	/* Select standard mode by default */
	iface->cur_mode |= KW_I2C_MODE_STANDARD;
	
	/* Write mode */
	write_reg(reg_mode, iface->cur_mode);
	
	/* Switch interrupts off & clear them*/
	write_reg(reg_ier, 0x00);
	write_reg(reg_isr, KW_I2C_IRQ_MASK);

#ifndef POLLED_MODE
	/* Request chip interrupt */	
	rc = request_irq(iface->irq, keywest_irq, SA_INTERRUPT, "keywest i2c", iface);
	if (rc) {
		printk(KERN_ERR "i2c-keywest: can't get IRQ %d !\n", iface->irq);
		iounmap(iface->base);
		kfree(iface);
		pmac_low_i2c_unlock(np);
		return -ENODEV;
	}
#endif /* POLLED_MODE */

	pmac_low_i2c_unlock(np);
	dev_set_drvdata(dev, iface);
	
	for (i=0; i<nchan; i++) {
		struct keywest_chan* chan = &iface->channels[i];
		u8 addr;
		
		sprintf(chan->adapter.name, "%s %d", np->parent->name, i);
		chan->iface = iface;
		chan->chan_no = i;
		chan->adapter.id = I2C_ALGO_SMBUS;
		chan->adapter.algo = &keywest_algorithm;
		chan->adapter.algo_data = NULL;
		chan->adapter.client_register = NULL;
		chan->adapter.client_unregister = NULL;
		i2c_set_adapdata(&chan->adapter, chan);
		chan->adapter.dev.parent = dev;

		rc = i2c_add_adapter(&chan->adapter);
		if (rc) {
			printk("i2c-keywest.c: Adapter %s registration failed\n",
				chan->adapter.name);
			i2c_set_adapdata(&chan->adapter, NULL);
		}
		if (probe) {
			printk("Probe: ");
			for (addr = 0x00; addr <= 0x7f; addr++) {
				if (i2c_smbus_xfer(&chan->adapter,addr,
				    0,0,0,I2C_SMBUS_QUICK,NULL) >= 0)
					printk("%02x ", addr);
			}
			printk("\n");
		}
	}

	printk(KERN_INFO "Found KeyWest i2c on \"%s\", %d channel%s, stepping: %d bits\n",
		np->parent->name, nchan, nchan > 1 ? "s" : "", bsteps);
		
	return 0;
}
Esempio n. 11
0
static int riic_i2c_probe(struct platform_device *pdev)
{
	struct riic_dev *riic;
	struct i2c_adapter *adap;
	struct resource *res;
	struct i2c_timings i2c_t;
	int i, ret;

	riic = devm_kzalloc(&pdev->dev, sizeof(*riic), GFP_KERNEL);
	if (!riic)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	riic->base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(riic->base))
		return PTR_ERR(riic->base);

	riic->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(riic->clk)) {
		dev_err(&pdev->dev, "missing controller clock");
		return PTR_ERR(riic->clk);
	}

	for (i = 0; i < ARRAY_SIZE(riic_irqs); i++) {
		res = platform_get_resource(pdev, IORESOURCE_IRQ, riic_irqs[i].res_num);
		if (!res)
			return -ENODEV;

		ret = devm_request_irq(&pdev->dev, res->start, riic_irqs[i].isr,
					0, riic_irqs[i].name, riic);
		if (ret) {
			dev_err(&pdev->dev, "failed to request irq %s\n", riic_irqs[i].name);
			return ret;
		}
	}

	adap = &riic->adapter;
	i2c_set_adapdata(adap, riic);
	strlcpy(adap->name, "Renesas RIIC adapter", sizeof(adap->name));
	adap->owner = THIS_MODULE;
	adap->algo = &riic_algo;
	adap->dev.parent = &pdev->dev;
	adap->dev.of_node = pdev->dev.of_node;

	init_completion(&riic->msg_done);

	i2c_parse_fw_timings(&pdev->dev, &i2c_t, true);

	pm_runtime_enable(&pdev->dev);

	ret = riic_init_hw(riic, &i2c_t);
	if (ret)
		goto out;

	ret = i2c_add_adapter(adap);
	if (ret)
		goto out;

	platform_set_drvdata(pdev, riic);

	dev_info(&pdev->dev, "registered with %dHz bus speed\n",
		 i2c_t.bus_freq_hz);
	return 0;

out:
	pm_runtime_disable(&pdev->dev);
	return ret;
}
Esempio n. 12
0
/* Platform driver interface */
static int zd1301_demod_probe(struct platform_device *pdev)
{
	struct zd1301_demod_dev *dev;
	struct zd1301_demod_platform_data *pdata = pdev->dev.platform_data;
	int ret;

	dev_dbg(&pdev->dev, "\n");

	if (!pdata) {
		ret = -EINVAL;
		dev_err(&pdev->dev, "cannot proceed without platform data\n");
		goto err;
	}
	if (!pdev->dev.parent->driver) {
		ret = -EINVAL;
		dev_dbg(&pdev->dev, "no parent device\n");
		goto err;
	}

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

	/* Setup the state */
	dev->pdev = pdev;
	dev->gain = zd1301_demod_gain;

	/* Sleep */
	ret = zd1301_demod_wreg(dev, 0x6840, 0x21);
	if (ret)
		goto err_kfree;
	ret = zd1301_demod_wreg(dev, 0x6a38, 0x07);
	if (ret)
		goto err_kfree;

	/* Create I2C adapter */
	strlcpy(dev->adapter.name, "ZyDAS ZD1301 demod", sizeof(dev->adapter.name));
	dev->adapter.algo = &zd1301_demod_i2c_algorithm;
	dev->adapter.algo_data = NULL;
	dev->adapter.dev.parent = pdev->dev.parent;
	i2c_set_adapdata(&dev->adapter, dev);
	ret = i2c_add_adapter(&dev->adapter);
	if (ret) {
		dev_err(&pdev->dev, "I2C adapter add failed %d\n", ret);
		goto err_kfree;
	}

	/* Create dvb frontend */
	memcpy(&dev->frontend.ops, &zd1301_demod_ops, sizeof(dev->frontend.ops));
	dev->frontend.demodulator_priv = dev;
	platform_set_drvdata(pdev, dev);
	dev_info(&pdev->dev, "ZyDAS ZD1301 demod attached\n");

	return 0;
err_kfree:
	kfree(dev);
err:
	dev_dbg(&pdev->dev, "failed=%d\n", ret);
	return ret;
}
Esempio n. 13
0
static int amd756_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
	int nforce = (id->driver_data == NFORCE);
	int error;
	u8 temp;
	
	if (amd756_ioport) {
		dev_err(&pdev->dev, "Only one device supported "
		       "(you have a strange motherboard, btw)\n");
		return -ENODEV;
	}

	if (nforce) {
		if (PCI_FUNC(pdev->devfn) != 1)
			return -ENODEV;

		pci_read_config_word(pdev, SMBBANFORCE, &amd756_ioport);
		amd756_ioport &= 0xfffc;
	} else { /* amd */
		if (PCI_FUNC(pdev->devfn) != 3)
			return -ENODEV;

		pci_read_config_byte(pdev, SMBGCFG, &temp);
		if ((temp & 128) == 0) {
			dev_err(&pdev->dev,
				"Error: SMBus controller I/O not enabled!\n");
			return -ENODEV;
		}

		/* Determine the address of the SMBus areas */
		/* Technically it is a dword but... */
		pci_read_config_word(pdev, SMBBA, &amd756_ioport);
		amd756_ioport &= 0xff00;
		amd756_ioport += SMB_ADDR_OFFSET;
	}

	error = acpi_check_region(amd756_ioport, SMB_IOSIZE,
				  amd756_driver.name);
	if (error)
		return -ENODEV;

	if (!request_region(amd756_ioport, SMB_IOSIZE, amd756_driver.name)) {
		dev_err(&pdev->dev, "SMB region 0x%x already in use!\n",
			amd756_ioport);
		return -ENODEV;
	}

	pci_read_config_byte(pdev, SMBREV, &temp);
	dev_dbg(&pdev->dev, "SMBREV = 0x%X\n", temp);
	dev_dbg(&pdev->dev, "AMD756_smba = 0x%X\n", amd756_ioport);

	/* set up the sysfs linkage to our parent device */
	amd756_smbus.dev.parent = &pdev->dev;

	snprintf(amd756_smbus.name, sizeof(amd756_smbus.name),
		 "SMBus %s adapter at %04x", chipname[id->driver_data],
		 amd756_ioport);

	error = i2c_add_adapter(&amd756_smbus);
	if (error)
		goto out_err;

	return 0;

 out_err:
	release_region(amd756_ioport, SMB_IOSIZE);
	return error;
}
Esempio n. 14
0
/* fixme: add vbi stuff here */
static int dpc_probe(struct saa7146_dev* dev)
{
	struct dpc* dpc = NULL;

	dpc = kzalloc(sizeof(struct dpc), GFP_KERNEL);
	if( NULL == dpc ) {
		printk("dpc_v4l2.o: dpc_probe: not enough kernel memory.\n");
		return -ENOMEM;
	}

	/* FIXME: enable i2c-port pins, video-port-pins
	   video port pins should be enabled here ?! */
	saa7146_write(dev, MC1, (MASK_08 | MASK_24 | MASK_10 | MASK_26));

	dpc->i2c_adapter = (struct i2c_adapter) {
		.class = I2C_CLASS_TV_ANALOG,
		.name = "dpc7146",
	};
	saa7146_i2c_adapter_prepare(dev, &dpc->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
	if(i2c_add_adapter(&dpc->i2c_adapter) < 0) {
		DEB_S(("cannot register i2c-device. skipping.\n"));
		kfree(dpc);
		return -EFAULT;
	}

	/* loop through all i2c-devices on the bus and look who is there */
	device_for_each_child(&dpc->i2c_adapter.dev, dpc, dpc_check_clients);

	/* check if all devices are present */
	if (!dpc->saa7111a) {
		DEB_D(("dpc_v4l2.o: dpc_attach failed for this device.\n"));
		i2c_del_adapter(&dpc->i2c_adapter);
		kfree(dpc);
		return -ENODEV;
	}

	/* all devices are present, probe was successful */
	DEB_D(("dpc_v4l2.o: dpc_probe succeeded for this device.\n"));

	/* we store the pointer in our private data field */
	dev->ext_priv = dpc;

	return 0;
}

/* bring hardware to a sane state. this has to be done, just in case someone
   wants to capture from this device before it has been properly initialized.
   the capture engine would badly fail, because no valid signal arrives on the
   saa7146, thus leading to timeouts and stuff. */
static int dpc_init_done(struct saa7146_dev* dev)
{
	struct dpc* dpc = (struct dpc*)dev->ext_priv;

	DEB_D(("dpc_v4l2.o: dpc_init_done called.\n"));

	/* initialize the helper ics to useful values */
	i2c_smbus_write_byte_data(dpc->saa7111a, 0x00, 0x11);

	i2c_smbus_write_byte_data(dpc->saa7111a, 0x02, 0xc0);
	i2c_smbus_write_byte_data(dpc->saa7111a, 0x03, 0x30);
	i2c_smbus_write_byte_data(dpc->saa7111a, 0x04, 0x00);
	i2c_smbus_write_byte_data(dpc->saa7111a, 0x05, 0x00);
	i2c_smbus_write_byte_data(dpc->saa7111a, 0x06, 0xde);
	i2c_smbus_write_byte_data(dpc->saa7111a, 0x07, 0xad);
	i2c_smbus_write_byte_data(dpc->saa7111a, 0x08, 0xa8);
	i2c_smbus_write_byte_data(dpc->saa7111a, 0x09, 0x00);
	i2c_smbus_write_byte_data(dpc->saa7111a, 0x0a, 0x80);
	i2c_smbus_write_byte_data(dpc->saa7111a, 0x0b, 0x47);
	i2c_smbus_write_byte_data(dpc->saa7111a, 0x0c, 0x40);
	i2c_smbus_write_byte_data(dpc->saa7111a, 0x0d, 0x00);
	i2c_smbus_write_byte_data(dpc->saa7111a, 0x0e, 0x03);

	i2c_smbus_write_byte_data(dpc->saa7111a, 0x10, 0xd0);
	i2c_smbus_write_byte_data(dpc->saa7111a, 0x11, 0x1c);
	i2c_smbus_write_byte_data(dpc->saa7111a, 0x12, 0xc1);
	i2c_smbus_write_byte_data(dpc->saa7111a, 0x13, 0x30);

	i2c_smbus_write_byte_data(dpc->saa7111a, 0x1f, 0x81);

	return 0;
}

static struct saa7146_ext_vv vv_data;

/* this function only gets called when the probing was successful */
static int dpc_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
{
	struct dpc* dpc = (struct dpc*)dev->ext_priv;

	DEB_D(("dpc_v4l2.o: dpc_attach called.\n"));

	/* checking for i2c-devices can be omitted here, because we
	   already did this in "dpc_vl42_probe" */

	saa7146_vv_init(dev,&vv_data);
	if( 0 != saa7146_register_device(&dpc->video_dev, dev, "dpc", VFL_TYPE_GRABBER)) {
		ERR(("cannot register capture v4l2 device. skipping.\n"));
		return -1;
	}

	/* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
	if( 0 != DPC_BOARD_CAN_DO_VBI(dev)) {
		if( 0 != saa7146_register_device(&dpc->vbi_dev, dev, "dpc", VFL_TYPE_VBI)) {
			ERR(("cannot register vbi v4l2 device. skipping.\n"));
		}
	}

	i2c_use_client(dpc->saa7111a);

	printk("dpc: found 'dpc7146 demonstration board'-%d.\n",dpc_num);
	dpc_num++;

	/* the rest */
	dpc->cur_input = 0;
	dpc_init_done(dev);

	return 0;
}

static int dpc_detach(struct saa7146_dev* dev)
{
	struct dpc* dpc = (struct dpc*)dev->ext_priv;

	DEB_EE(("dev:%p\n",dev));

	i2c_release_client(dpc->saa7111a);

	saa7146_unregister_device(&dpc->video_dev,dev);
	if( 0 != DPC_BOARD_CAN_DO_VBI(dev)) {
		saa7146_unregister_device(&dpc->vbi_dev,dev);
	}
	saa7146_vv_release(dev);

	dpc_num--;

	i2c_del_adapter(&dpc->i2c_adapter);
	kfree(dpc);
	return 0;
}

#ifdef axa
int dpc_vbi_bypass(struct saa7146_dev* dev)
{
	struct dpc* dpc = (struct dpc*)dev->ext_priv;

	int i = 1;

	/* switch bypass in saa7111a */
	if ( 0 != dpc->saa7111a->driver->command(dpc->saa7111a,SAA711X_VBI_BYPASS, &i)) {
		printk("dpc_v4l2.o: VBI_BYPASS: could not address saa7111a.\n");
		return -1;
	}

	return 0;
}
#endif

static int dpc_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
{
	struct saa7146_dev *dev = fh->dev;
	struct dpc* dpc = (struct dpc*)dev->ext_priv;
/*
	struct saa7146_vv *vv = dev->vv_data;
*/
	switch(cmd)
	{
	case VIDIOC_ENUMINPUT:
	{
		struct v4l2_input *i = arg;
		DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index));

		if( i->index < 0 || i->index >= DPC_INPUTS) {
			return -EINVAL;
		}

		memcpy(i, &dpc_inputs[i->index], sizeof(struct v4l2_input));

		DEB_D(("dpc_v4l2.o: v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n",i->index));
		return 0;
	}
	case VIDIOC_G_INPUT:
	{
		int *input = (int *)arg;
		*input = dpc->cur_input;

		DEB_D(("dpc_v4l2.o: VIDIOC_G_INPUT: %d\n",*input));
		return 0;
	}
	case VIDIOC_S_INPUT:
	{
		int	input = *(int *)arg;

		if (input < 0 || input >= DPC_INPUTS) {
			return -EINVAL;
		}

		dpc->cur_input = input;

		/* fixme: switch input here, switch audio, too! */
//		saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, input_port_selection[input].hps_sync);
		printk("dpc_v4l2.o: VIDIOC_S_INPUT: fixme switch input.\n");

		return 0;
	}
	default:
/*
		DEB_D(("dpc_v4l2.o: v4l2_ioctl does not handle this ioctl.\n"));
*/
		return -ENOIOCTLCMD;
	}
	return 0;
}

static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
{
	return 0;
}

static struct saa7146_standard standard[] = {
	{
		.name	= "PAL", 	.id	= V4L2_STD_PAL,
		.v_offset	= 0x17,	.v_field 	= 288,
		.h_offset	= 0x14,	.h_pixels 	= 680,
		.v_max_out	= 576,	.h_max_out	= 768,
	}, {
		.name	= "NTSC", 	.id	= V4L2_STD_NTSC,
Esempio n. 15
0
static int dc_i2c_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct dc_i2c *i2c;
	struct resource *r;
	int ret = 0, irq;

	i2c = devm_kzalloc(&pdev->dev, sizeof(struct dc_i2c), GFP_KERNEL);
	if (!i2c)
		return -ENOMEM;

	if (of_property_read_u32(pdev->dev.of_node, "clock-frequency",
				 &i2c->frequency))
		i2c->frequency = DEFAULT_FREQ;

	i2c->dev = &pdev->dev;
	platform_set_drvdata(pdev, i2c);

	spin_lock_init(&i2c->lock);
	init_completion(&i2c->done);

	i2c->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(i2c->clk))
		return PTR_ERR(i2c->clk);

	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	i2c->regs = devm_ioremap_resource(&pdev->dev, r);
	if (IS_ERR(i2c->regs))
		return PTR_ERR(i2c->regs);

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return irq;

	ret = devm_request_irq(&pdev->dev, irq, dc_i2c_irq, 0,
			       dev_name(&pdev->dev), i2c);
	if (ret < 0)
		return ret;

	strlcpy(i2c->adap.name, "Conexant Digicolor I2C adapter",
		sizeof(i2c->adap.name));
	i2c->adap.owner = THIS_MODULE;
	i2c->adap.algo = &dc_i2c_algorithm;
	i2c->adap.dev.parent = &pdev->dev;
	i2c->adap.dev.of_node = np;
	i2c->adap.algo_data = i2c;

	ret = dc_i2c_init_hw(i2c);
	if (ret)
		return ret;

	ret = clk_prepare_enable(i2c->clk);
	if (ret < 0)
		return ret;

	ret = i2c_add_adapter(&i2c->adap);
	if (ret < 0) {
		clk_unprepare(i2c->clk);
		return ret;
	}

	return 0;
}
Esempio n. 16
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;
	u32 sr;

	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);

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return irq;

	pdata = dev_get_platdata(&pdev->dev);

	/* 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;

	spin_lock_init(&i2c->lock);
	init_waitqueue_head(&i2c->wait);

	ret = devm_request_threaded_irq(&pdev->dev, irq, xiic_isr,
					xiic_process, IRQF_ONESHOT,
					pdev->name, i2c);

	if (ret < 0) {
		dev_err(&pdev->dev, "Cannot claim IRQ\n");
		return ret;
	}

	/*
	 * Detect endianness
	 * Try to reset the TX FIFO. Then check the EMPTY flag. If it is not
	 * set, assume that the endianness was wrong and swap.
	 */
	i2c->endianness = LITTLE;
	xiic_setreg32(i2c, XIIC_CR_REG_OFFSET, XIIC_CR_TX_FIFO_RESET_MASK);
	/* Reset is cleared in xiic_reinit */
	sr = xiic_getreg32(i2c, XIIC_SR_REG_OFFSET);
	if (!(sr & XIIC_SR_TX_FIFO_EMPTY_MASK))
		i2c->endianness = BIG;

	xiic_reinit(i2c);

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

	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);
	}

	return 0;
}
Esempio n. 17
0
static int wmt_i2c_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct wmt_i2c_dev *i2c_dev;
	struct i2c_adapter *adap;
	struct resource *res;
	int err;
	u32 clk_rate;

	i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL);
	if (!i2c_dev)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	i2c_dev->base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(i2c_dev->base))
		return PTR_ERR(i2c_dev->base);

	i2c_dev->irq = irq_of_parse_and_map(np, 0);
	if (!i2c_dev->irq) {
		dev_err(&pdev->dev, "irq missing or invalid\n");
		return -EINVAL;
	}

	i2c_dev->clk = of_clk_get(np, 0);
	if (IS_ERR(i2c_dev->clk)) {
		dev_err(&pdev->dev, "unable to request clock\n");
		return PTR_ERR(i2c_dev->clk);
	}

	i2c_dev->mode = I2C_MODE_STANDARD;
	err = of_property_read_u32(np, "clock-frequency", &clk_rate);
	if ((!err) && (clk_rate == 400000))
		i2c_dev->mode = I2C_MODE_FAST;

	i2c_dev->dev = &pdev->dev;

	err = devm_request_irq(&pdev->dev, i2c_dev->irq, wmt_i2c_isr, 0,
							"i2c", i2c_dev);
	if (err) {
		dev_err(&pdev->dev, "failed to request irq %i\n", i2c_dev->irq);
		return err;
	}

	adap = &i2c_dev->adapter;
	i2c_set_adapdata(adap, i2c_dev);
	strlcpy(adap->name, "WMT I2C adapter", sizeof(adap->name));
	adap->owner = THIS_MODULE;
	adap->algo = &wmt_i2c_algo;
	adap->dev.parent = &pdev->dev;
	adap->dev.of_node = pdev->dev.of_node;

	init_completion(&i2c_dev->complete);

	err = wmt_i2c_reset_hardware(i2c_dev);
	if (err) {
		dev_err(&pdev->dev, "error initializing hardware\n");
		return err;
	}

	err = i2c_add_adapter(adap);
	if (err) {
		dev_err(&pdev->dev, "failed to add adapter\n");
		return err;
	}

	platform_set_drvdata(pdev, i2c_dev);

	return 0;
}
Esempio n. 18
0
static int mxb_probe(struct saa7146_dev* dev)
{
	struct mxb* mxb = NULL;
	int result;

	if ((result = request_module("saa7111")) < 0) {
		printk("mxb: saa7111 i2c module not available.\n");
		return -ENODEV;
	}
	if ((result = request_module("tea6420")) < 0) {
		printk("mxb: tea6420 i2c module not available.\n");
		return -ENODEV;
	}
	if ((result = request_module("tea6415c")) < 0) {
		printk("mxb: tea6415c i2c module not available.\n");
		return -ENODEV;
	}
	if ((result = request_module("tda9840")) < 0) {
		printk("mxb: tda9840 i2c module not available.\n");
		return -ENODEV;
	}
	if ((result = request_module("tuner")) < 0) {
		printk("mxb: tuner i2c module not available.\n");
		return -ENODEV;
	}

	mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL);
	if( NULL == mxb ) {
		DEB_D(("not enough kernel memory.\n"));
		return -ENOMEM;
	}

	mxb->i2c_adapter = (struct i2c_adapter) {
		.class = I2C_CLASS_TV_ANALOG,
		.name = "mxb",
	};

	saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
	if(i2c_add_adapter(&mxb->i2c_adapter) < 0) {
		DEB_S(("cannot register i2c-device. skipping.\n"));
		kfree(mxb);
		return -EFAULT;
	}

	/* loop through all i2c-devices on the bus and look who is there */
	device_for_each_child(&mxb->i2c_adapter.dev, mxb, mxb_check_clients);

	/* check if all devices are present */
	if (!mxb->tea6420_1 || !mxb->tea6420_2 || !mxb->tea6415c ||
	    !mxb->tda9840 || !mxb->saa7111a || !mxb->tuner) {
		printk("mxb: did not find all i2c devices. aborting\n");
		i2c_del_adapter(&mxb->i2c_adapter);
		kfree(mxb);
		return -ENODEV;
	}

	/* all devices are present, probe was successful */

	/* we store the pointer in our private data field */
	dev->ext_priv = mxb;

	return 0;
}

/* some init data for the saa7740, the so-called 'sound arena module'.
   there are no specs available, so we simply use some init values */
static struct {
	int	length;
	char	data[9];
} mxb_saa7740_init[] = {
	{ 3, { 0x80, 0x00, 0x00 } },{ 3, { 0x80, 0x89, 0x00 } },
	{ 3, { 0x80, 0xb0, 0x0a } },{ 3, { 0x00, 0x00, 0x00 } },
	{ 3, { 0x49, 0x00, 0x00 } },{ 3, { 0x4a, 0x00, 0x00 } },
	{ 3, { 0x4b, 0x00, 0x00 } },{ 3, { 0x4c, 0x00, 0x00 } },
	{ 3, { 0x4d, 0x00, 0x00 } },{ 3, { 0x4e, 0x00, 0x00 } },
	{ 3, { 0x4f, 0x00, 0x00 } },{ 3, { 0x50, 0x00, 0x00 } },
	{ 3, { 0x51, 0x00, 0x00 } },{ 3, { 0x52, 0x00, 0x00 } },
	{ 3, { 0x53, 0x00, 0x00 } },{ 3, { 0x54, 0x00, 0x00 } },
	{ 3, { 0x55, 0x00, 0x00 } },{ 3, { 0x56, 0x00, 0x00 } },
	{ 3, { 0x57, 0x00, 0x00 } },{ 3, { 0x58, 0x00, 0x00 } },
	{ 3, { 0x59, 0x00, 0x00 } },{ 3, { 0x5a, 0x00, 0x00 } },
	{ 3, { 0x5b, 0x00, 0x00 } },{ 3, { 0x5c, 0x00, 0x00 } },
	{ 3, { 0x5d, 0x00, 0x00 } },{ 3, { 0x5e, 0x00, 0x00 } },
	{ 3, { 0x5f, 0x00, 0x00 } },{ 3, { 0x60, 0x00, 0x00 } },
	{ 3, { 0x61, 0x00, 0x00 } },{ 3, { 0x62, 0x00, 0x00 } },
	{ 3, { 0x63, 0x00, 0x00 } },{ 3, { 0x64, 0x00, 0x00 } },
	{ 3, { 0x65, 0x00, 0x00 } },{ 3, { 0x66, 0x00, 0x00 } },
	{ 3, { 0x67, 0x00, 0x00 } },{ 3, { 0x68, 0x00, 0x00 } },
	{ 3, { 0x69, 0x00, 0x00 } },{ 3, { 0x6a, 0x00, 0x00 } },
	{ 3, { 0x6b, 0x00, 0x00 } },{ 3, { 0x6c, 0x00, 0x00 } },
	{ 3, { 0x6d, 0x00, 0x00 } },{ 3, { 0x6e, 0x00, 0x00 } },
	{ 3, { 0x6f, 0x00, 0x00 } },{ 3, { 0x70, 0x00, 0x00 } },
	{ 3, { 0x71, 0x00, 0x00 } },{ 3, { 0x72, 0x00, 0x00 } },
	{ 3, { 0x73, 0x00, 0x00 } },{ 3, { 0x74, 0x00, 0x00 } },
	{ 3, { 0x75, 0x00, 0x00 } },{ 3, { 0x76, 0x00, 0x00 } },
	{ 3, { 0x77, 0x00, 0x00 } },{ 3, { 0x41, 0x00, 0x42 } },
	{ 3, { 0x42, 0x10, 0x42 } },{ 3, { 0x43, 0x20, 0x42 } },
	{ 3, { 0x44, 0x30, 0x42 } },{ 3, { 0x45, 0x00, 0x01 } },
	{ 3, { 0x46, 0x00, 0x01 } },{ 3, { 0x47, 0x00, 0x01 } },
	{ 3, { 0x48, 0x00, 0x01 } },
	{ 9, { 0x01, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
	{ 9, { 0x21, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
	{ 9, { 0x09, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
	{ 9, { 0x29, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
	{ 9, { 0x11, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
	{ 9, { 0x31, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
	{ 9, { 0x19, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
	{ 9, { 0x39, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
	{ 9, { 0x05, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
	{ 9, { 0x25, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
	{ 9, { 0x0d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
	{ 9, { 0x2d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
	{ 9, { 0x15, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
	{ 9, { 0x35, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
	{ 9, { 0x1d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
	{ 9, { 0x3d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
	{ 3, { 0x80, 0xb3, 0x0a } },
	{-1, { 0} }
};

static const unsigned char mxb_saa7111_init[] = {
	0x00, 0x00,	  /* 00 - ID byte */
	0x01, 0x00,	  /* 01 - reserved */

	/*front end */
	0x02, 0xd8,	  /* 02 - FUSE=x, GUDL=x, MODE=x */
	0x03, 0x23,	  /* 03 - HLNRS=0, VBSL=1, WPOFF=0, HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */
	0x04, 0x00,	  /* 04 - GAI1=256 */
	0x05, 0x00,	  /* 05 - GAI2=256 */

	/* decoder */
	0x06, 0xf0,	  /* 06 - HSB at  xx(50Hz) /  xx(60Hz) pixels after end of last line */
	0x07, 0x30,	  /* 07 - HSS at  xx(50Hz) /  xx(60Hz) pixels after end of last line */
	0x08, 0xa8,	  /* 08 - AUFD=x, FSEL=x, EXFIL=x, VTRC=x, HPLL=x, VNOI=x */
	0x09, 0x02,	  /* 09 - BYPS=x, PREF=x, BPSS=x, VBLB=x, UPTCV=x, APER=x */
	0x0a, 0x80,	  /* 0a - BRIG=128 */
	0x0b, 0x47,	  /* 0b - CONT=1.109 */
	0x0c, 0x40,	  /* 0c - SATN=1.0 */
	0x0d, 0x00,	  /* 0d - HUE=0 */
	0x0e, 0x01,	  /* 0e - CDTO=0, CSTD=0, DCCF=0, FCTC=0, CHBW=1 */
	0x0f, 0x00,	  /* 0f - reserved */
	0x10, 0xd0,	  /* 10 - OFTS=x, HDEL=x, VRLN=x, YDEL=x */
	0x11, 0x8c,	  /* 11 - GPSW=x, CM99=x, FECO=x, COMPO=x, OEYC=1, OEHV=1, VIPB=0, COLO=0 */
	0x12, 0x80,	  /* 12 - xx output control 2 */
	0x13, 0x30,	  /* 13 - xx output control 3 */
	0x14, 0x00,	  /* 14 - reserved */
	0x15, 0x15,	  /* 15 - VBI */
	0x16, 0x04,	  /* 16 - VBI */
	0x17, 0x00,	  /* 17 - VBI */
};

/* bring hardware to a sane state. this has to be done, just in case someone
   wants to capture from this device before it has been properly initialized.
   the capture engine would badly fail, because no valid signal arrives on the
   saa7146, thus leading to timeouts and stuff. */
static int mxb_init_done(struct saa7146_dev* dev)
{
	struct mxb* mxb = (struct mxb*)dev->ext_priv;
	struct video_decoder_init init;
	struct i2c_msg msg;
	struct tuner_setup tun_setup;
	v4l2_std_id std = V4L2_STD_PAL_BG;

	int i = 0, err = 0;
	struct	tea6415c_multiplex vm;

	/* select video mode in saa7111a */
	i = VIDEO_MODE_PAL;
	/* fixme: currently pointless: gets overwritten by configuration below */
	mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_NORM, &i);

	/* write configuration to saa7111a */
	init.data = mxb_saa7111_init;
	init.len = sizeof(mxb_saa7111_init);
	mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_INIT, &init);

	/* select tuner-output on saa7111a */
	i = 0;
	mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_INPUT, &i);

	/* enable vbi bypass */
	i = 1;
	mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_VBI_BYPASS, &i);

	/* select a tuner type */
	tun_setup.mode_mask = T_ANALOG_TV;
	tun_setup.addr = ADDR_UNSET;
	tun_setup.type = TUNER_PHILIPS_PAL;
	mxb->tuner->driver->command(mxb->tuner,TUNER_SET_TYPE_ADDR, &tun_setup);
	/* tune in some frequency on tuner */
	mxb->cur_freq.tuner = 0;
	mxb->cur_freq.type = V4L2_TUNER_ANALOG_TV;
	mxb->cur_freq.frequency = freq;
	mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY,
					&mxb->cur_freq);

	/* set a default video standard */
	mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);

	/* mute audio on tea6420s */
	mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[6][0]);
	mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[6][1]);
	mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[6][0]);
	mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_cd[6][1]);

	/* switch to tuner-channel on tea6415c*/
	vm.out = 17;
	vm.in  = 3;
	mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm);

	/* select tuner-output on multicable on tea6415c*/
	vm.in  = 3;
	vm.out = 13;
	mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm);

	/* the rest for mxb */
	mxb->cur_input = 0;
	mxb->cur_mute = 1;

	mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
	mxb->tda9840->driver->command(mxb->tda9840, TDA9840_SWITCH, &mxb->cur_mode);

	/* check if the saa7740 (aka 'sound arena module') is present
	   on the mxb. if so, we must initialize it. due to lack of
	   informations about the saa7740, the values were reverse
	   engineered. */
	msg.addr = 0x1b;
	msg.flags = 0;
	msg.len = mxb_saa7740_init[0].length;
	msg.buf = &mxb_saa7740_init[0].data[0];

	if( 1 == (err = i2c_transfer(&mxb->i2c_adapter, &msg, 1))) {
		/* the sound arena module is a pos, that's probably the reason
		   philips refuses to hand out a datasheet for the saa7740...
		   it seems to screw up the i2c bus, so we disable fast irq
		   based i2c transactions here and rely on the slow and safe
		   polling method ... */
		extension.flags &= ~SAA7146_USE_I2C_IRQ;
		for(i = 1;;i++) {
			if( -1 == mxb_saa7740_init[i].length ) {
				break;
			}

			msg.len = mxb_saa7740_init[i].length;
			msg.buf = &mxb_saa7740_init[i].data[0];
			if( 1 != (err = i2c_transfer(&mxb->i2c_adapter, &msg, 1))) {
				DEB_D(("failed to initialize 'sound arena module'.\n"));
				goto err;
			}
		}
		INFO(("'sound arena module' detected.\n"));
	}
err:
	/* the rest for saa7146: you should definitely set some basic values
	   for the input-port handling of the saa7146. */

	/* ext->saa has been filled by the core driver */

	/* some stuff is done via variables */
	saa7146_set_hps_source_and_sync(dev, input_port_selection[mxb->cur_input].hps_source, input_port_selection[mxb->cur_input].hps_sync);

	/* some stuff is done via direct write to the registers */

	/* this is ugly, but because of the fact that this is completely
	   hardware dependend, it should be done directly... */
	saa7146_write(dev, DD1_STREAM_B,	0x00000000);
	saa7146_write(dev, DD1_INIT,		0x02000200);
	saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));

	return 0;
}

/* interrupt-handler. this gets called when irq_mask is != 0.
   it must clear the interrupt-bits in irq_mask it has handled */
/*
void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask)
{
	struct mxb* mxb = (struct mxb*)dev->ext_priv;
}
*/

static struct saa7146_ext_vv vv_data;

/* this function only gets called when the probing was successful */
static int mxb_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
{
	struct mxb* mxb = (struct mxb*)dev->ext_priv;

	DEB_EE(("dev:%p\n",dev));

	/* checking for i2c-devices can be omitted here, because we
	   already did this in "mxb_vl42_probe" */

	saa7146_vv_init(dev,&vv_data);
	if( 0 != saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
		ERR(("cannot register capture v4l2 device. skipping.\n"));
		return -1;
	}

	/* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
	if( 0 != MXB_BOARD_CAN_DO_VBI(dev)) {
		if( 0 != saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
			ERR(("cannot register vbi v4l2 device. skipping.\n"));
		}
	}

	i2c_use_client(mxb->tea6420_1);
	i2c_use_client(mxb->tea6420_2);
	i2c_use_client(mxb->tea6415c);
	i2c_use_client(mxb->tda9840);
	i2c_use_client(mxb->saa7111a);
	i2c_use_client(mxb->tuner);

	printk("mxb: found 'Multimedia eXtension Board'-%d.\n",mxb_num);

	mxb_num++;
	mxb_init_done(dev);
	return 0;
}

static int mxb_detach(struct saa7146_dev* dev)
{
	struct mxb* mxb = (struct mxb*)dev->ext_priv;

	DEB_EE(("dev:%p\n",dev));

	i2c_release_client(mxb->tea6420_1);
	i2c_release_client(mxb->tea6420_2);
	i2c_release_client(mxb->tea6415c);
	i2c_release_client(mxb->tda9840);
	i2c_release_client(mxb->saa7111a);
	i2c_release_client(mxb->tuner);

	saa7146_unregister_device(&mxb->video_dev,dev);
	if( 0 != MXB_BOARD_CAN_DO_VBI(dev)) {
		saa7146_unregister_device(&mxb->vbi_dev,dev);
	}
	saa7146_vv_release(dev);

	mxb_num--;

	i2c_del_adapter(&mxb->i2c_adapter);
	kfree(mxb);

	return 0;
}

static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
{
	struct saa7146_dev *dev = fh->dev;
	struct mxb* mxb = (struct mxb*)dev->ext_priv;
	struct saa7146_vv *vv = dev->vv_data;

	switch(cmd) {
	case VIDIOC_ENUMINPUT:
	{
		struct v4l2_input *i = arg;

		DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index));
		if( i->index < 0 || i->index >= MXB_INPUTS) {
			return -EINVAL;
		}
		memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));

		return 0;
	}
	/* the saa7146 provides some controls (brightness, contrast, saturation)
	   which gets registered *after* this function. because of this we have
	   to return with a value != 0 even if the function succeded.. */
	case VIDIOC_QUERYCTRL:
	{
		struct v4l2_queryctrl *qc = arg;
		int i;

		for (i = MAXCONTROLS - 1; i >= 0; i--) {
			if (mxb_controls[i].id == qc->id) {
				*qc = mxb_controls[i];
				DEB_D(("VIDIOC_QUERYCTRL %d.\n",qc->id));
				return 0;
			}
		}
		return -EAGAIN;
	}
	case VIDIOC_G_CTRL:
	{
		struct v4l2_control *vc = arg;
		int i;

		for (i = MAXCONTROLS - 1; i >= 0; i--) {
			if (mxb_controls[i].id == vc->id) {
				break;
			}
		}

		if( i < 0 ) {
			return -EAGAIN;
		}

		switch (vc->id ) {
			case V4L2_CID_AUDIO_MUTE: {
				vc->value = mxb->cur_mute;
				DEB_D(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n",vc->value));
				return 0;
			}
		}

		DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n",vc->value));
		return 0;
	}

	case VIDIOC_S_CTRL:
	{
		struct	v4l2_control	*vc = arg;
		int i = 0;

		for (i = MAXCONTROLS - 1; i >= 0; i--) {
			if (mxb_controls[i].id == vc->id) {
				break;
			}
		}

		if( i < 0 ) {
			return -EAGAIN;
		}

		switch (vc->id ) {
			case V4L2_CID_AUDIO_MUTE: {
				mxb->cur_mute = vc->value;
				if( 0 == vc->value ) {
					/* switch the audio-source */
					mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[mxb->cur_input]][0]);
					mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[mxb->cur_input]][1]);
				} else {
					mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[6][0]);
					mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[6][1]);
				}
				DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n",vc->value));
				break;
			}
		}
		return 0;
	}
	case VIDIOC_G_INPUT:
	{
		int *input = (int *)arg;
		*input = mxb->cur_input;

		DEB_EE(("VIDIOC_G_INPUT %d.\n",*input));
		return 0;
	}
	case VIDIOC_S_INPUT:
	{
		int input = *(int *)arg;
		struct	tea6415c_multiplex vm;
		int i = 0;

		DEB_EE(("VIDIOC_S_INPUT %d.\n",input));

		if (input < 0 || input >= MXB_INPUTS) {
			return -EINVAL;
		}

		/* fixme: locke das setzen des inputs mit hilfe des mutexes
		mutex_lock(&dev->lock);
		video_mux(dev,*i);
		mutex_unlock(&dev->lock);
		*/

		/* fixme: check if streaming capture
		if ( 0 != dev->streaming ) {
			DEB_D(("VIDIOC_S_INPUT illegal while streaming.\n"));
			return -EPERM;
		}
		*/

		mxb->cur_input = input;

		saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, input_port_selection[input].hps_sync);

		/* prepare switching of tea6415c and saa7111a;
		   have a look at the 'background'-file for further informations  */
		switch( input ) {

			case TUNER:
			{
				i = 0;
				vm.in  = 3;
				vm.out = 17;

			if ( 0 != mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm)) {
					printk("VIDIOC_S_INPUT: could not address tea6415c #1\n");
					return -EFAULT;
				}
				/* connect tuner-output always to multicable */
				vm.in  = 3;
				vm.out = 13;
				break;
			}
			case AUX3_YC:
			{
				/* nothing to be done here. aux3_yc is
				   directly connected to the saa711a */
				i = 5;
				break;
			}
			case AUX3:
			{
				/* nothing to be done here. aux3 is
				   directly connected to the saa711a */
				i = 1;
				break;
			}
			case AUX1:
			{
				i = 0;
				vm.in  = 1;
				vm.out = 17;
				break;
			}
		}

		/* switch video in tea6415c only if necessary */
		switch( input ) {
			case TUNER:
			case AUX1:
			{
				if ( 0 != mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm)) {
					printk("VIDIOC_S_INPUT: could not address tea6415c #3\n");
					return -EFAULT;
				}
				break;
			}
			default:
			{
				break;
			}
		}

		/* switch video in saa7111a */
		if ( 0 != mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_INPUT, &i)) {
			printk("VIDIOC_S_INPUT: could not address saa7111a #1.\n");
		}

		/* switch the audio-source only if necessary */
		if( 0 == mxb->cur_mute ) {
			mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[input]][0]);
			mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[input]][1]);
		}

		return 0;
	}
	case VIDIOC_G_TUNER:
	{
		struct v4l2_tuner *t = arg;
		int byte = 0;

		if( 0 != t->index ) {
			DEB_D(("VIDIOC_G_TUNER: channel %d does not have a tuner attached.\n", t->index));
			return -EINVAL;
		}

		DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));

		memset(t,0,sizeof(*t));
		strcpy(t->name, "Television");

		t->type = V4L2_TUNER_ANALOG_TV;
		t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
		t->rangelow = 772;	/* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */
		t->rangehigh = 13684;	/* 855.25 MHz / 62.5 kHz = 13684 */
		/* FIXME: add the real signal strength here */
		t->signal = 0xffff;
		t->afc = 0;

		mxb->tda9840->driver->command(mxb->tda9840,TDA9840_DETECT, &byte);
		t->audmode = mxb->cur_mode;

		if( byte < 0 ) {
			t->rxsubchans  = V4L2_TUNER_SUB_MONO;
		} else {
			switch(byte) {
				case TDA9840_MONO_DETECT: {
					t->rxsubchans 	= V4L2_TUNER_SUB_MONO;
					DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_MONO.\n"));
					break;
				}
				case TDA9840_DUAL_DETECT: {
					t->rxsubchans 	= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
					DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_LANG1.\n"));
					break;
				}
				case TDA9840_STEREO_DETECT: {
					t->rxsubchans 	= V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
					DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_STEREO.\n"));
					break;
				}
				default: { /* TDA9840_INCORRECT_DETECT */
					t->rxsubchans 	= V4L2_TUNER_MODE_MONO;
					DEB_D(("VIDIOC_G_TUNER: TDA9840_INCORRECT_DETECT => V4L2_TUNER_MODE_MONO\n"));
					break;
				}
			}
		}

		return 0;
	}
	case VIDIOC_S_TUNER:
	{
		struct v4l2_tuner *t = arg;
		int result = 0;
		int byte = 0;

		if( 0 != t->index ) {
			DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n",t->index));
			return -EINVAL;
		}

		switch(t->audmode) {
			case V4L2_TUNER_MODE_STEREO: {
				mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
				byte = TDA9840_SET_STEREO;
				DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n"));
				break;
			}
			case V4L2_TUNER_MODE_LANG1_LANG2: {
				mxb->cur_mode = V4L2_TUNER_MODE_LANG1_LANG2;
				byte = TDA9840_SET_BOTH;
				DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1_LANG2\n"));
				break;
			}
			case V4L2_TUNER_MODE_LANG1: {
				mxb->cur_mode = V4L2_TUNER_MODE_LANG1;
				byte = TDA9840_SET_LANG1;
				DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n"));
				break;
			}
			case V4L2_TUNER_MODE_LANG2: {
				mxb->cur_mode = V4L2_TUNER_MODE_LANG2;
				byte = TDA9840_SET_LANG2;
				DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n"));
				break;
			}
			default: { /* case V4L2_TUNER_MODE_MONO: {*/
				mxb->cur_mode = V4L2_TUNER_MODE_MONO;
				byte = TDA9840_SET_MONO;
				DEB_D(("VIDIOC_S_TUNER: TDA9840_SET_MONO\n"));
				break;
			}
		}

		if( 0 != (result = mxb->tda9840->driver->command(mxb->tda9840, TDA9840_SWITCH, &byte))) {
			printk("VIDIOC_S_TUNER error. result:%d, byte:%d\n",result,byte);
		}

		return 0;
	}
	case VIDIOC_G_FREQUENCY:
	{
		struct v4l2_frequency *f = arg;

		if(0 != mxb->cur_input) {
			DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n",mxb->cur_input));
			return -EINVAL;
		}

		*f = mxb->cur_freq;

		DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq.frequency));
		return 0;
	}
	case VIDIOC_S_FREQUENCY:
	{
		struct v4l2_frequency *f = arg;

		if (0 != f->tuner)
			return -EINVAL;

		if (V4L2_TUNER_ANALOG_TV != f->type)
			return -EINVAL;

		if(0 != mxb->cur_input) {
			DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n",mxb->cur_input));
			return -EINVAL;
		}

		mxb->cur_freq = *f;
		DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency));

		/* tune in desired frequency */
		mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY, &mxb->cur_freq);

		/* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
		spin_lock(&dev->slock);
		vv->vbi_fieldcount = 0;
		spin_unlock(&dev->slock);

		return 0;
	}
	case MXB_S_AUDIO_CD:
	{
		int i = *(int*)arg;

		if( i < 0 || i >= MXB_AUDIOS ) {
			DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n",i));
			return -EINVAL;
		}

		DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n",i));

		mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[i][0]);
		mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_cd[i][1]);

		return 0;
	}
	case MXB_S_AUDIO_LINE:
	{
		int i = *(int*)arg;

		if( i < 0 || i >= MXB_AUDIOS ) {
			DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n",i));
			return -EINVAL;
		}

		DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n",i));
		mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[i][0]);
		mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[i][1]);

		return 0;
	}
	case VIDIOC_G_AUDIO:
	{
		struct v4l2_audio *a = arg;

		if( a->index < 0 || a->index > MXB_INPUTS ) {
			DEB_D(("VIDIOC_G_AUDIO %d out of range.\n",a->index));
			return -EINVAL;
		}

		DEB_EE(("VIDIOC_G_AUDIO %d.\n",a->index));
		memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio));

		return 0;
	}
	case VIDIOC_S_AUDIO:
	{
		struct v4l2_audio *a = arg;
		DEB_D(("VIDIOC_S_AUDIO %d.\n",a->index));
		return 0;
	}
	default:
/*
		DEB2(printk("does not handle this ioctl.\n"));
*/
		return -ENOIOCTLCMD;
	}
	return 0;
}

static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
{
	struct mxb* mxb = (struct mxb*)dev->ext_priv;
	int zero = 0;
	int one = 1;

	if(V4L2_STD_PAL_I == std->id ) {
		v4l2_std_id std = V4L2_STD_PAL_I;
		DEB_D(("VIDIOC_S_STD: setting mxb for PAL_I.\n"));
		/* set the 7146 gpio register -- I don't know what this does exactly */
		saa7146_write(dev, GPIO_CTRL, 0x00404050);
		/* unset the 7111 gpio register -- I don't know what this does exactly */
		mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &zero);
		mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
	} else {
		v4l2_std_id std = V4L2_STD_PAL_BG;
		DEB_D(("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM.\n"));
		/* set the 7146 gpio register -- I don't know what this does exactly */
		saa7146_write(dev, GPIO_CTRL, 0x00404050);
		/* set the 7111 gpio register -- I don't know what this does exactly */
		mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &one);
		mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
	}
	return 0;
}

static struct saa7146_standard standard[] = {
	{
		.name	= "PAL-BG", 	.id	= V4L2_STD_PAL_BG,
		.v_offset	= 0x17,	.v_field 	= 288,
		.h_offset	= 0x14,	.h_pixels 	= 680,
		.v_max_out	= 576,	.h_max_out	= 768,
	}, {
		.name	= "PAL-I", 	.id	= V4L2_STD_PAL_I,
Esempio n. 19
0
static int hix5hd2_i2c_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct hix5hd2_i2c_priv *priv;
	struct resource *mem;
	unsigned int freq;
	int irq, ret;

	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	if (of_property_read_u32(np, "clock-frequency", &freq)) {
		/* use 100k as default value */
		priv->freq = 100000;
	} else {
		if (freq > HIX5I2C_MAX_FREQ) {
			priv->freq = HIX5I2C_MAX_FREQ;
			dev_warn(priv->dev, "use max freq %d instead\n",
				 HIX5I2C_MAX_FREQ);
		} else {
			priv->freq = freq;
		}
	}

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	priv->regs = devm_ioremap_resource(&pdev->dev, mem);
	if (IS_ERR(priv->regs))
		return PTR_ERR(priv->regs);

	irq = platform_get_irq(pdev, 0);
	if (irq <= 0) {
		dev_err(&pdev->dev, "cannot find HS-I2C IRQ\n");
		return irq;
	}

	priv->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(priv->clk)) {
		dev_err(&pdev->dev, "cannot get clock\n");
		return PTR_ERR(priv->clk);
	}
	clk_prepare_enable(priv->clk);

	strlcpy(priv->adap.name, "hix5hd2-i2c", sizeof(priv->adap.name));
	priv->dev = &pdev->dev;
	priv->adap.owner = THIS_MODULE;
	priv->adap.algo = &hix5hd2_i2c_algorithm;
	priv->adap.retries = 3;
	priv->adap.dev.of_node = np;
	priv->adap.algo_data = priv;
	priv->adap.dev.parent = &pdev->dev;
	i2c_set_adapdata(&priv->adap, priv);
	platform_set_drvdata(pdev, priv);
	spin_lock_init(&priv->lock);
	init_completion(&priv->msg_complete);

	hix5hd2_i2c_init(priv);

	ret = devm_request_irq(&pdev->dev, irq, hix5hd2_i2c_irq,
			       IRQF_NO_SUSPEND | IRQF_ONESHOT,
			       dev_name(&pdev->dev), priv);
	if (ret != 0) {
		dev_err(&pdev->dev, "cannot request HS-I2C IRQ %d\n", irq);
		goto err_clk;
	}

	pm_suspend_ignore_children(&pdev->dev, true);
	pm_runtime_set_autosuspend_delay(priv->dev, MSEC_PER_SEC);
	pm_runtime_use_autosuspend(priv->dev);
	pm_runtime_set_active(priv->dev);
	pm_runtime_enable(priv->dev);

	ret = i2c_add_adapter(&priv->adap);
	if (ret < 0)
		goto err_runtime;

	return ret;

err_runtime:
	pm_runtime_disable(priv->dev);
	pm_runtime_set_suspended(priv->dev);
err_clk:
	clk_disable_unprepare(priv->clk);
	return ret;
}
static int __devinit ocores_i2c_probe(struct platform_device *pdev)
{
	struct ocores_i2c *i2c;
	struct ocores_i2c_platform_data *pdata;
	struct resource *res, *res2;
	int ret;
	int i;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res)
		return -ENODEV;

	res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!res2)
		return -ENODEV;

	pdata = (struct ocores_i2c_platform_data*) pdev->dev.platform_data;
	if (!pdata)
		return -ENODEV;

	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;
	}

	i2c->regstep = pdata->regstep;
	i2c->clock_khz = pdata->clock_khz;
	ocores_init(i2c);

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

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

	/* 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;
	}

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

	return 0;

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

	return ret;
}
Esempio n. 21
0
static int qup_i2c_probe(struct platform_device *pdev)
{
	static const int blk_sizes[] = {4, 16, 32};
	struct device_node *node = pdev->dev.of_node;
	struct qup_i2c_dev *qup;
	unsigned long one_bit_t;
	struct resource *res;
	u32 io_mode, hw_ver, size;
	int ret, fs_div, hs_div;
	int src_clk_freq;
	u32 clk_freq = 100000;

	qup = devm_kzalloc(&pdev->dev, sizeof(*qup), GFP_KERNEL);
	if (!qup)
		return -ENOMEM;

	qup->dev = &pdev->dev;
	init_completion(&qup->xfer);
	platform_set_drvdata(pdev, qup);

	of_property_read_u32(node, "clock-frequency", &clk_freq);

	/* We support frequencies up to FAST Mode (400KHz) */
	if (!clk_freq || clk_freq > 400000) {
		dev_err(qup->dev, "clock frequency not supported %d\n",
			clk_freq);
		return -EINVAL;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	qup->base = devm_ioremap_resource(qup->dev, res);
	if (IS_ERR(qup->base))
		return PTR_ERR(qup->base);

	qup->irq = platform_get_irq(pdev, 0);
	if (qup->irq < 0) {
		dev_err(qup->dev, "No IRQ defined\n");
		return qup->irq;
	}

	qup->clk = devm_clk_get(qup->dev, "core");
	if (IS_ERR(qup->clk)) {
		dev_err(qup->dev, "Could not get core clock\n");
		return PTR_ERR(qup->clk);
	}

	qup->pclk = devm_clk_get(qup->dev, "iface");
	if (IS_ERR(qup->pclk)) {
		dev_err(qup->dev, "Could not get iface clock\n");
		return PTR_ERR(qup->pclk);
	}

	qup_i2c_enable_clocks(qup);

	/*
	 * Bootloaders might leave a pending interrupt on certain QUP's,
	 * so we reset the core before registering for interrupts.
	 */
	writel(1, qup->base + QUP_SW_RESET);
	ret = qup_i2c_poll_state_valid(qup);
	if (ret)
		goto fail;

	ret = devm_request_irq(qup->dev, qup->irq, qup_i2c_interrupt,
			       IRQF_TRIGGER_HIGH, "i2c_qup", qup);
	if (ret) {
		dev_err(qup->dev, "Request %d IRQ failed\n", qup->irq);
		goto fail;
	}
	disable_irq(qup->irq);

	hw_ver = readl(qup->base + QUP_HW_VERSION);
	dev_dbg(qup->dev, "Revision %x\n", hw_ver);

	io_mode = readl(qup->base + QUP_IO_MODE);

	/*
	 * The block/fifo size w.r.t. 'actual data' is 1/2 due to 'tag'
	 * associated with each byte written/received
	 */
	size = QUP_OUTPUT_BLOCK_SIZE(io_mode);
	if (size >= ARRAY_SIZE(blk_sizes)) {
		ret = -EIO;
		goto fail;
	}
	qup->out_blk_sz = blk_sizes[size] / 2;

	size = QUP_INPUT_BLOCK_SIZE(io_mode);
	if (size >= ARRAY_SIZE(blk_sizes)) {
		ret = -EIO;
		goto fail;
	}
	qup->in_blk_sz = blk_sizes[size] / 2;

	size = QUP_OUTPUT_FIFO_SIZE(io_mode);
	qup->out_fifo_sz = qup->out_blk_sz * (2 << size);

	size = QUP_INPUT_FIFO_SIZE(io_mode);
	qup->in_fifo_sz = qup->in_blk_sz * (2 << size);

	src_clk_freq = clk_get_rate(qup->clk);
	fs_div = ((src_clk_freq / clk_freq) / 2) - 3;
	hs_div = 3;
	qup->clk_ctl = (hs_div << 8) | (fs_div & 0xff);

	/*
	 * Time it takes for a byte to be clocked out on the bus.
	 * Each byte takes 9 clock cycles (8 bits + 1 ack).
	 */
	one_bit_t = (USEC_PER_SEC / clk_freq) + 1;
	qup->one_byte_t = one_bit_t * 9;

	dev_dbg(qup->dev, "IN:block:%d, fifo:%d, OUT:block:%d, fifo:%d\n",
		qup->in_blk_sz, qup->in_fifo_sz,
		qup->out_blk_sz, qup->out_fifo_sz);

	i2c_set_adapdata(&qup->adap, qup);
	qup->adap.algo = &qup_i2c_algo;
	qup->adap.dev.parent = qup->dev;
	qup->adap.dev.of_node = pdev->dev.of_node;
	strlcpy(qup->adap.name, "QUP I2C adapter", sizeof(qup->adap.name));

	ret = i2c_add_adapter(&qup->adap);
	if (ret)
		goto fail;

	pm_runtime_set_autosuspend_delay(qup->dev, MSEC_PER_SEC);
	pm_runtime_use_autosuspend(qup->dev);
	pm_runtime_set_active(qup->dev);
	pm_runtime_enable(qup->dev);
	return 0;

fail:
	qup_i2c_disable_clocks(qup);
	return ret;
}
Esempio n. 22
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 out;
	}
	dev_info(i2c->dev, "version %s\n", DRV_VERSION);

	return 0;

out:
	return result;
};
Esempio n. 23
0
static int __devinit i2c_pnx_probe(struct platform_device *pdev)
{
	unsigned long tmp;
	int ret = 0;
	struct i2c_pnx_algo_data *alg_data;
	int freq_mhz;
	struct i2c_pnx_data *i2c_pnx = pdev->dev.platform_data;

	if (!i2c_pnx || !i2c_pnx->adapter) {
		dev_err(&pdev->dev, "%s: no platform data supplied\n",
		       __FUNCTION__);
		ret = -EINVAL;
		goto out;
	}

	platform_set_drvdata(pdev, i2c_pnx);

	if (i2c_pnx->calculate_input_freq)
		freq_mhz = i2c_pnx->calculate_input_freq(pdev);
	else {
		freq_mhz = PNX_DEFAULT_FREQ;
		dev_info(&pdev->dev, "Setting bus frequency to default value: "
		       "%d MHz", freq_mhz);
	}

	i2c_pnx->adapter->algo = &pnx_algorithm;

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

	/* Register I/O resource */
	if (!request_region(alg_data->base, I2C_PNX_REGION_SIZE, pdev->name)) {
		dev_err(&pdev->dev,
		       "I/O region 0x%08x for I2C already in use.\n",
		       alg_data->base);
		ret = -ENODEV;
		goto out_drvdata;
	}

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

	i2c_pnx->set_clock_run(pdev);

	/*
	 * 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_mhz * 1000) / I2C_PNX_SPEED_KHZ) / 2 - 2;
	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(I2C_PNX_TIMEOUT, alg_data)) {
		ret = -ENODEV;
		goto out_unmap;
	}
	init_completion(&alg_data->mif.complete);

	ret = request_irq(alg_data->irq, i2c_pnx_interrupt,
			0, pdev->name, i2c_pnx->adapter);
	if (ret)
		goto out_clock;

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

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

	return 0;

out_irq:
	free_irq(alg_data->irq, alg_data);
out_clock:
	i2c_pnx->set_clock_stop(pdev);
out_unmap:
	iounmap((void *)alg_data->ioaddr);
out_release:
	release_region(alg_data->base, I2C_PNX_REGION_SIZE);
out_drvdata:
	platform_set_drvdata(pdev, NULL);
out:
	return ret;
}
Esempio n. 24
0
static int i2c_pxa_probe(struct platform_device *dev)
{
	struct pxa_i2c *i2c = &i2c_pxa;
	struct resource *res;
#ifdef CONFIG_I2C_PXA_SLAVE
	struct i2c_pxa_platform_data *plat = dev->dev.platform_data;
#endif
	int ret;
	int irq;

	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
	irq = platform_get_irq(dev, 0);
	if (res == NULL || irq < 0)
		return -ENODEV;

	if (!request_mem_region(res->start, res_len(res), res->name))
		return -ENOMEM;

	i2c = kmalloc(sizeof(struct pxa_i2c), GFP_KERNEL);
	if (!i2c) {
		ret = -ENOMEM;
		goto emalloc;
	}

	memcpy(i2c, &i2c_pxa, sizeof(struct pxa_i2c));
	init_waitqueue_head(&i2c->wait);
	i2c->adap.name[strlen(i2c->adap.name) - 1] = '0' + dev->id % 10;

	i2c->reg_base = ioremap(res->start, res_len(res));
	if (!i2c->reg_base) {
		ret = -EIO;
		goto eremap;
	}

	i2c->iobase = res->start;
	i2c->iosize = res_len(res);

	i2c->irq = irq;

	i2c->slave_addr = I2C_PXA_SLAVE_ADDR;

#ifdef CONFIG_I2C_PXA_SLAVE
	if (plat) {
		i2c->slave_addr = plat->slave_addr;
		i2c->slave = plat->slave;
	}
#endif

	switch (dev->id) {
	case 0:
#ifdef CONFIG_PXA27x
		pxa_gpio_mode(GPIO117_I2CSCL_MD);
		pxa_gpio_mode(GPIO118_I2CSDA_MD);
#endif
		pxa_set_cken(CKEN14_I2C, 1);
		break;
#ifdef CONFIG_PXA27x
	case 1:
		local_irq_disable();
		PCFR |= PCFR_PI2CEN;
		local_irq_enable();
		pxa_set_cken(CKEN15_PWRI2C, 1);
#endif
	}

	ret = request_irq(irq, i2c_pxa_handler, IRQF_DISABLED,
			  i2c->adap.name, i2c);
	if (ret)
		goto ereqirq;


	i2c_pxa_reset(i2c);

	i2c->adap.algo_data = i2c;
	i2c->adap.dev.parent = &dev->dev;

	ret = i2c_add_adapter(&i2c->adap);
	if (ret < 0) {
		printk(KERN_INFO "I2C: Failed to add bus\n");
		goto eadapt;
	}

	platform_set_drvdata(dev, i2c);

#ifdef CONFIG_I2C_PXA_SLAVE
	printk(KERN_INFO "I2C: %s: PXA I2C adapter, slave address %d\n",
	       i2c->adap.dev.bus_id, i2c->slave_addr);
#else
	printk(KERN_INFO "I2C: %s: PXA I2C adapter\n",
	       i2c->adap.dev.bus_id);
#endif
	return 0;

eadapt:
	free_irq(irq, i2c);
ereqirq:
	switch (dev->id) {
	case 0:
		pxa_set_cken(CKEN14_I2C, 0);
		break;
#ifdef CONFIG_PXA27x
	case 1:
		pxa_set_cken(CKEN15_PWRI2C, 0);
		local_irq_disable();
		PCFR &= ~PCFR_PI2CEN;
		local_irq_enable();
#endif
	}
eremap:
	kfree(i2c);
emalloc:
	release_mem_region(res->start, res_len(res));
	return ret;
}
Esempio n. 25
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_register_i2c_devices(&dev->adap, node);

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