コード例 #1
0
ファイル: PmodTMP3.c プロジェクト: Digilent/vivado-library
/***	TMP3_WriteIIC
**
**	Parameters:
**		InstancePtr - PmodTMP3 object to initialize
**		reg			- Register to send to
**		Data		- Pointer to data buffer to send
**		nData		- Number of data values to send
**
**	Return Value:
**		none
**
**	Errors:
**		none
**
**	Description:
**		Writes nData data bytes to register reg
**
*/
void TMP3_WriteIIC(PmodTMP3* InstancePtr, u8 reg, u8 *Data, int nData)
{
	u8 out[10];
	out[0]=reg;
	out[1]=*Data;
	int Status;

	if (InstancePtr->currentRegister!=reg){
			InstancePtr->currentRegister=reg;
	}
	Status = XIic_Start(&InstancePtr->TMP3Iic);
	if (Status != XST_SUCCESS) {
		return;
	}
	XIic_Send(InstancePtr->TMP3Iic.BaseAddress, InstancePtr->chipAddr, out, nData+1, XIIC_STOP);

	//XIic_MasterSend(&InstancePtr->TMP3Iic, out, nData+1);

	//XIic_DynMasterSend(&InstancePtr->TMP3Iic, out, nData+1);

	//while(XIic_IsIicBusy(&InstancePtr->TMP3Iic));

	Status = XIic_Stop(&InstancePtr->TMP3Iic);
	if (Status != XST_SUCCESS) {
		return;
	}

}
コード例 #2
0
ファイル: PmodTMP3.c プロジェクト: Digilent/vivado-library
/***	TMP3_ReadIIC
**
**	Parameters:
**		InstancePtr - PmodTMP3 object to initialize
**		reg			- Register to read from
**		Data		- Pointer to recieve buffer
**		nData		- Number of data values to read
**
**	Return Value:
**		none
**
**	Errors:
**		none
**
**	Description:
**		Reads nData data bytes from register reg
**
*/
void TMP3_ReadIIC(PmodTMP3* InstancePtr, u8 reg, u8 *Data, int nData)
{
	int Status;
	Status = XIic_Start(&InstancePtr->TMP3Iic);
	if (Status != XST_SUCCESS) {
		return;
	}
	if (InstancePtr->currentRegister!=reg){
		//XIic_MasterSend(&InstancePtr->TMP3Iic, &reg, 1);
		XIic_Send(InstancePtr->TMP3Iic.BaseAddress, InstancePtr->chipAddr, &reg, 1, XII_REPEATED_START_OPTION);
		InstancePtr->currentRegister=reg;
	}//else{
		//XIic_MasterRecv(&InstancePtr->TMP3Iic, Data, nData);
	//}
	XIic_Recv(InstancePtr->TMP3Iic.BaseAddress, InstancePtr->chipAddr, Data, nData, XIIC_STOP);


	//XIic_MasterSend(&InstancePtr->TMP3Iic, &reg, 2);
	//InstancePtr->recvbytes=nData+1;
	//InstancePtr->recv=Data;
	//XIic_MasterRecv(&InstancePtr->TMP3Iic, Data, nData);

	Status = XIic_Stop(&InstancePtr->TMP3Iic);
	if (Status != XST_SUCCESS) {
		return;
	}
}
コード例 #3
0
ファイル: PmodTMP3.c プロジェクト: Digilent/vivado-library
int TMP3_IICInit(XIic *IicInstancePtr){
	int Status;

	Status = XIic_CfgInitialize(IicInstancePtr, &TMP3_Config, TMP3_Config.BaseAddress);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}



	/*
	 * Start the IIC driver so that the device is enabled.
	 */
	XIic_Start(IicInstancePtr);

	/*
	 * Disable Global interrupt to use polled mode operation
	 */
	XIic_IntrGlobalDisable(IicInstancePtr);

	return XST_SUCCESS;

}
コード例 #4
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;
}
コード例 #5
0
static int
xiic_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
{
    struct xiic_data *dev = (struct xiic_data *) i2c_adap;
    struct i2c_msg *pmsg;
    u32 options;
    int i, retries;
    u32 Status;
    u32 writeop;
	
    for (i = 0; i < num; i++)
    {
        pmsg = &msgs[i];

        if (!pmsg->len) /* If length is zero */
             continue;  /* on to the next request. */

        /*
         * This code checks up to 16 times for the
         * bus busy condition.
         */
        retries = 4;
        while((XIic_IsIicBusy(&dev->Iic) == TRUE) &&
              (retries-- != 0))
        {
            set_current_state(TASK_INTERRUPTIBLE);
            schedule_timeout(HZ/250);
        }


        /* If bus is still busy, bail */
        if (XIic_IsIicBusy(&dev->Iic) == TRUE)
        {
            printk(KERN_WARNING
                   "%s #%d: Could not talk to device 0x%2x (%d), bus always busy, trying to reset\n",
                   dev->adap.name, dev->index, pmsg->addr,
                   dev->status_intr_flag);

			/* Try stopping, reseting and starting device to clear condition
			*/
			if (XIic_Stop(&dev->Iic) != XST_SUCCESS)
			{
				/* The bus was in use.. */
				printk(KERN_WARNING
					   "%s #%d: Could not stop device. Restart from higher layer.\n",
					   dev->adap.name, dev->index);
				return -ENXIO;
			}
			else
			{
				XIic_Reset(&dev->Iic);
				if (XIic_Start(&dev->Iic) != XST_SUCCESS)
				{
					printk(KERN_ERR "%s #%d: Could not start device.\n",
						   dev->adap.name, dev->index);
					return -ENODEV;
				}

				return -ENXIO;
			}
        }

        options = 0;
        if (pmsg->flags & I2C_M_TEN)
            options |= XII_SEND_10_BIT_OPTION;
        XIic_SetOptions(&dev->Iic, options);

        if (XIic_SetAddress(&dev->Iic, XII_ADDR_TO_SEND_TYPE,
                    pmsg->addr) != XST_SUCCESS)
        {
            printk(KERN_WARNING
                   "%s #%d: Could not set address to 0x%2x.\n",
                   dev->adap.name, dev->index, pmsg->addr);
            return -EIO;
        }


        dev->transmit_intr_flag = 0xFFFFFFFF;
        dev->receive_intr_flag = 0xFFFFFFFF;
        dev->status_intr_flag = 0xFFFFFFFF;

        /* set the writeop flag to 0 so the adapter does not wait
         * at bottom of loop
         */
        writeop = 0;

		dev->Iic.Stats.TxErrors = 0;

        if (pmsg->flags & I2C_M_RD)
        {
            Status = XIic_MasterRecv(&dev->Iic, pmsg->buf, pmsg->len);
        }
        else
        {
            Status = XIic_MasterSend(&dev->Iic, pmsg->buf, pmsg->len);
        }

        if (Status != XST_SUCCESS)
        {
            printk(KERN_WARNING
                   "%s #%d: Unexpected error %d.\n",
                   dev->adap.name, dev->index, (int)Status);
            return -EIO;
        }

        /*
	 * Wait till the data is transmitted or received. If there is an error
	 * retry for 10 times.
	 */
	retries = 10;

	if(pmsg->flags & I2C_M_RD)
	{
		while((((volatile int)(dev->receive_intr_flag)) != 0) && (retries != 0))
		{
			if ( dev->Iic.Stats.TxErrors != 0)
			{
				udelay(25);
				Status = XIic_MasterRecv(&dev->Iic, pmsg->buf, pmsg->len);
				dev->Iic.Stats.TxErrors = 0;
				retries--;
			}

			/* the udelay was not working for Microblaze and this seems
			   like a better solution */	
			schedule_timeout_interruptible(1);
                }
	}
	else
	{
		while((((volatile int)(dev->transmit_intr_flag)) != 0) && (retries != 0))
		{
			if ( dev->Iic.Stats.TxErrors != 0)
			{
				udelay(25);
				Status = XIic_MasterSend(&dev->Iic, pmsg->buf, pmsg->len);
				dev->Iic.Stats.TxErrors = 0;
				retries--;
			}

			/* the udelay was not working for Microblaze and this seems
			   like a better solution */	
			schedule_timeout_interruptible(1);
		}
	}

	if(retries == 0)
	{
		printk("Unable to talk to Device\n");
		printk("Wrong Slave address or Slave device Busy\n");
	}
    }
    return num;
}
コード例 #6
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;
}
コード例 #7
0
/*
 * *********************************************************
 * IicWriteData with address added as an input parameter
 * *********************************************************
 */
int IicWriteData(u8 IicAddr, u8 *BufferPtr, u16 ByteCount)
{
	int Status;
	u32 IicTimeoutCounter = 0;

	// Mark the Transmit Flag
	TransmitComplete = 1;
	IicInstance.Stats.TxErrors = 0;

	/*
	 * Start Iic Device
	 */
	Status = XIic_Start(&IicInstance);
	if (Status != XST_SUCCESS) {
#ifdef IIC_DEBUG
		xil_printf("IicWriteData: IIC Start Device Failed with status %x\r\n", Status);
#endif
		return XST_FAILURE;
	}

	/*
	 * Set Iic Address
	 */
	Status = XIic_SetAddress(&IicInstance, XII_ADDR_TO_SEND_TYPE, IicAddr);
	if (Status != XST_SUCCESS) {
#ifdef IIC_DEBUG
		xil_printf("IicWriteData: IIC Set Address Failed with status %x\r\n", Status);
#endif
		return XST_FAILURE;
	}

	/*
	 * Send the Data
	 */
	Status = XIic_MasterSend(&IicInstance, BufferPtr, ByteCount);
	if (Status != XST_SUCCESS) {
#ifdef IIC_DEBUG
		xil_printf("IicWriteData: IIC Master Send failed with status %x\r\n", Status);
#endif
		return XST_FAILURE;
	}

	/*
	 * Wait till the transmission is completed
	 */
	while(((TransmitComplete) || (XIic_IsIicBusy(&IicInstance)==TRUE)) && IicTimeoutCounter <= IIC_TIMEOUT) {
		IicTimeoutCounter++;
	}

	if (IicTimeoutCounter > IIC_TIMEOUT) {
		TransmitComplete = 0;
		XIic_Reset(&IicInstance);
		Status = XIic_Stop(&IicInstance);
#ifdef IIC_DEBUG
		xil_printf("IicWriteData: IIC Write Timeout!\r\n");
		if (Status != XST_SUCCESS) {
			xil_printf("IicWriteData: IIC stop failed with status %x\r\n", Status);
		}
#endif
		return XST_FAILURE;
	}

	/*
	 * Stop Iic Device
	 */
	Status = XIic_Stop(&IicInstance);
	if (Status != XST_SUCCESS) {
#ifdef IIC_DEBUG
		xil_printf("IicWriteData: IIC Stop failed with status %x\r\n", Status);
#endif
		return XST_FAILURE;
	}

	return XST_SUCCESS;
}
コード例 #8
0
/*
 * *********************************************************
 * IicReadData3 with address added as an input parameter - two bytes address
 * *********************************************************
 */
int IicReadData3(u8 IicAddr, u16 addr, u8 *BufferPtr, u16 ByteCount)
{
	int Status;
	u8 IicOptions;
	u32 IicTimeoutCounter = 0;

	/*
	 * Set Receive Flag
	 */
	ReceiveComplete = 1;

	/*
	 * Start Iic Device
	 */
	Status = XIic_Start(&IicInstance);
	if (Status != XST_SUCCESS) {
#ifdef IIC_DEBUG
		xil_printf("IicReadData3: IIC Start failed with status %x\r\n", Status);
#endif
		return XST_FAILURE;
	}

	/*
	 * Set Iic Address
	 */
	Status = XIic_SetAddress(&IicInstance, XII_ADDR_TO_SEND_TYPE, IicAddr);
	if (Status != XST_SUCCESS) {
#ifdef IIC_DEBUG
		xil_printf("IicReadData3: IIC Set Address failed with status %x\r\n", Status);
#endif
		return XST_FAILURE;
	}

	/*
	 * Write addr to the device
	 */
	// Mark the Transmit Flag
	TransmitComplete = 1;
	IicInstance.Stats.TxErrors = 0;

	/*
	 * Send the Data
	 */
	u8 addrReorder[2];
	u8 *addrPtr;
	addrPtr = &addr;
	addrReorder[0] = addrPtr[1];
	addrReorder[1] = addrPtr[0];
	Status = XIic_MasterSend(&IicInstance, addrReorder, 2);
	if (Status != XST_SUCCESS) {
#ifdef IIC_DEBUG
		xil_printf("IicReadData3: IIC Master Send failed with status %x\r\n", Status);
#endif
		return XST_FAILURE;
	}

	/*
	 * Wait till the transmission is completed
	 */
	while(((TransmitComplete) || (XIic_IsIicBusy(&IicInstance)==TRUE)) && IicTimeoutCounter <= IIC_TIMEOUT) {
		IicTimeoutCounter ++;
	}

	/*
	 * Handle Tx Timeout
	 */
	if (IicTimeoutCounter > IIC_TIMEOUT) {
		XIic_Reset(&IicInstance);
		Status = XIic_Stop(&IicInstance);
#ifdef IIC_DEBUG
		xil_printf("IicReadData3: IIC Write Timeout!\r\n");
		if (Status != XST_SUCCESS) {
			xil_printf("IicReadData3: IIC Stop Failed with status %x\r\n", Status);
		}
#endif
		return XST_FAILURE;
	}

	/*
	 * Receive Data
	 */
	Status = XIic_MasterRecv(&IicInstance, BufferPtr, ByteCount);
	if(Status != XST_SUCCESS) {
		if (Status != XST_SUCCESS) {
#ifdef IIC_DEBUG
			xil_printf("IicReadData3: IIC Master Recv Failed with status %x\r\n", Status);
#endif
			return XST_FAILURE;
		}
	}

	/*
	 * Wait until all the data is received
	 */
	IicTimeoutCounter = 0;
	while(((ReceiveComplete) || (XIic_IsIicBusy(&IicInstance)==TRUE)) && IicTimeoutCounter <= IIC_TIMEOUT) {
		IicTimeoutCounter ++;
	}

	/*
	 * Handle Rx Timeout
	 */
	if (IicTimeoutCounter > IIC_TIMEOUT) {
		XIic_Reset(&IicInstance);
		Status = XIic_Stop(&IicInstance);
#ifdef IIC_DEBUG
		xil_printf("IicReadData3: IIC Recv Timeout!\r\n");
		if (Status != XST_SUCCESS) {
			xil_printf("IicReadData3: IIC Stop Failed with status %x\r\n", Status);
		}
#endif
		return XST_FAILURE;
	}

	/*
	 * Stop Iic
	 */
	Status = XIic_Stop(&IicInstance);
	if (Status != XST_SUCCESS) {
#ifdef IIC_DEBUG
		xil_printf("IicReadData3: IIC Stop Failed with status %x\r\n", Status);
#endif
		return XST_FAILURE;
	}

	return XST_SUCCESS;
}
コード例 #9
0
ファイル: i2c-algo-xilinx.c プロジェクト: prime5711/blackbox
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;
}
コード例 #10
0
/**
* The function reads the temperature of the IIC temperature sensor on the
* IIC bus. It initializes the IIC device driver and sets it up to communicate
* with the temperature sensor. This function does contain a loop that polls
* for completion of the IIC processing such that it may not return if
* interrupts or the hardware are not working.
*
* @param	IicDeviceId is the XPAR_<IIC_instance>_DEVICE_ID value from
*		xparameters.h for the IIC Device
* @param	TempSensorAddress is the address of the Temperature Sensor device
*		on the IIC bus
* @param	TemperaturePtr is the data byte read from the temperature sensor
*
* @return	XST_SUCCESS to indicate success, else XST_FAILURE to indicate
*		a Failure.
*
* @note		None.
*
*******************************************************************************/
int TempSensorExample(u16 IicDeviceId, u8 TempSensorAddress, u8 *TemperaturePtr)
{
	int Status;
	static int Initialized = FALSE;
	XIic_Config *ConfigPtr;	/* Pointer to configuration data */

	if (!Initialized) {
		Initialized = TRUE;

		/*
		 * Initialize the IIC driver so that it is ready to use.
		 */
		ConfigPtr = XIic_LookupConfig(IicDeviceId);
		if (ConfigPtr == NULL) {
			return XST_FAILURE;
		}

		Status = XIic_CfgInitialize(&Iic, ConfigPtr,
						ConfigPtr->BaseAddress);
		if (Status != XST_SUCCESS) {
			return XST_FAILURE;
		}


		/*
		 * Setup handler to process the asynchronous events which occur,
		 * the driver is only interrupt driven such that this must be
		 * done prior to starting the device.
		 */
		XIic_SetRecvHandler(&Iic, (void *)&HandlerInfo, RecvHandler);
		XIic_SetStatusHandler(&Iic, (void *)&HandlerInfo,
						StatusHandler);

		/*
		 * Connect the ISR to the interrupt and enable interrupts.
		 */
		Status = SetupInterruptSystem(&Iic);
		if (Status != XST_SUCCESS) {
			return XST_FAILURE;
		}

		/*
		 * Start the IIC driver such that it is ready to send and
		 * receive messages on the IIC interface, set the address
		 * to send to which is the temperature sensor address
		 */
		XIic_Start(&Iic);
		XIic_SetAddress(&Iic, XII_ADDR_TO_SEND_TYPE, TempSensorAddress);
	}

	/*
	 * Clear updated flags such that they can be polled to indicate
	 * when the handler information has changed asynchronously and
	 * initialize the status which will be returned to a default value
	 */
	HandlerInfo.EventStatusUpdated = FALSE;
	HandlerInfo.RecvBytesUpdated = FALSE;
	Status = XST_FAILURE;

	/*
	 * Attempt to receive a byte of data from the temperature sensor
	 * on the IIC interface, ignore the return value since this example is
	 * a single master system such that the IIC bus should not ever be busy
	 */
	(void)XIic_MasterRecv(&Iic, TemperaturePtr, 1);

	/*
	 * The message is being received from the temperature sensor,
	 * wait for it to complete by polling the information that is
	 * updated asynchronously by interrupt processing
	 */
	while(1) {
		if(HandlerInfo.RecvBytesUpdated == TRUE) {
			/*
			 * The device information has been updated for receive
			 * processing,if all bytes received (1), indicate
			 * success
			 */
			if (HandlerInfo.RemainingRecvBytes == 0) {
				Status = XST_SUCCESS;
			}
			break;
		}

		/*
		 * Any event status which occurs indicates there was an error,
		 * so return unsuccessful, for this example there should be no
		 * status events since there is a single master on the bus
		 */
		if (HandlerInfo.EventStatusUpdated == TRUE) {
			break;
		}
	}

	return Status;
}