static inline void bus_reset_if_active(struct i2c_adapter *adap) { struct i2c_pnx_algo_data *alg_data = adap->algo_data; u32 stat; if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_active) { dev_err(&adap->dev, "%s: Bus is still active after xfer. Reset it...\n", adap->name); iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset, I2C_REG_CTL(alg_data)); wait_reset(I2C_PNX_TIMEOUT, alg_data); } else if (!(stat & mstatus_rfe) || !(stat & mstatus_tfe)) { /* If there is data in the fifo's after transfer, * flush fifo's by reset. */ iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset, I2C_REG_CTL(alg_data)); wait_reset(I2C_PNX_TIMEOUT, alg_data); } else if (stat & mstatus_nai) { iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset, I2C_REG_CTL(alg_data)); wait_reset(I2C_PNX_TIMEOUT, alg_data); } }
static inline void bus_reset_if_active(struct i2c_pnx_algo_data *alg_data) { u32 stat; if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_active) { dev_err(&alg_data->adapter.dev, "%s: Bus is still active after xfer. Reset it...\n", alg_data->adapter.name); iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset, I2C_REG_CTL(alg_data)); wait_reset(I2C_PNX_TIMEOUT, alg_data); } else if (!(stat & mstatus_rfe) || !(stat & mstatus_tfe)) { /* */ iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset, I2C_REG_CTL(alg_data)); wait_reset(I2C_PNX_TIMEOUT, alg_data); } else if (stat & mstatus_nai) { iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset, I2C_REG_CTL(alg_data)); wait_reset(I2C_PNX_TIMEOUT, alg_data); } }
int open_pclta( struct inode *inode, struct file *file ) { struct pclta_device *device = pclta_device_table[MINOR(inode->i_rdev)]; file->private_data = device; // file->f_op=&pclta_fops; karl test 13/07/2000 CALL_MSG("open_pclta()", ++pclta_call_level ); if( device == NULL ) { RETURN_MSG("open_pclta() ENXIO", pclta_call_level-- ); return -ENXIO; // no such device } if( device->state != Offline ) { RETURN_MSG("open_pclta() EBUSY", pclta_call_level-- ); return -EBUSY; // device busy } if( !open_device( device ) ) { RETURN_MSG("open_pclta() ENOMEM", pclta_call_level-- ); return -ENOMEM; // out of memory } // program interrupt request line // outb_p(irq_mask[device->interrupt], selirq_reg(device->base_address) ); //removed 07/07/200 karl. added init_hw below DEBUG_MSG("Base Addy=0x0%x ; IRQ=%d ; IRQ MASK = 0x0%x \n",device->base_address, device->interrupt ,pclta_irq_mask[device->interrupt]); init_hw( device->base_address, pclta_irq_mask[device->interrupt], device->txcvr_clock ); if( ! wait_reset(device->base_address, 500 ) ) { VERBOSE_MSG( "error(%d) PCLTA_LRESET.\n", PCLTA_LRESET ); return -EBUSY; } // waiting to leave reset state device->state = Idle; //enable_irq( device->interrupt ); // karl's test 07/07/2000 MOD_INC_USE_COUNT; RETURN_MSG("open_pclta() OK", pclta_call_level-- ); return 0; }
static void i2c_pnx_timeout(unsigned long data) { struct i2c_pnx_algo_data *alg_data = (struct i2c_pnx_algo_data *)data; u32 ctl; dev_err(&alg_data->adapter.dev, "Master timed out. stat = %04x, cntrl = %04x. Resetting master...\n", ioread32(I2C_REG_STS(alg_data)), ioread32(I2C_REG_CTL(alg_data))); /* Reset master and disable interrupts */ ctl = ioread32(I2C_REG_CTL(alg_data)); ctl &= ~(mcntrl_afie | mcntrl_naie | mcntrl_rffie | mcntrl_drmie); iowrite32(ctl, I2C_REG_CTL(alg_data)); ctl |= mcntrl_reset; iowrite32(ctl, I2C_REG_CTL(alg_data)); wait_reset(alg_data); alg_data->mif.ret = -EIO; complete(&alg_data->mif.complete); }
static int i2c_pnx_probe(struct platform_device *pdev) { unsigned long tmp; int ret = 0; struct i2c_pnx_algo_data *alg_data; unsigned long freq; struct resource *res; u32 speed = I2C_PNX_SPEED_KHZ_DEFAULT * 1000; alg_data = devm_kzalloc(&pdev->dev, sizeof(*alg_data), GFP_KERNEL); if (!alg_data) return -ENOMEM; platform_set_drvdata(pdev, alg_data); alg_data->adapter.dev.parent = &pdev->dev; alg_data->adapter.algo = &pnx_algorithm; alg_data->adapter.algo_data = alg_data; alg_data->adapter.nr = pdev->id; alg_data->timeout = I2C_PNX_TIMEOUT_DEFAULT; #ifdef CONFIG_OF alg_data->adapter.dev.of_node = of_node_get(pdev->dev.of_node); if (pdev->dev.of_node) { of_property_read_u32(pdev->dev.of_node, "clock-frequency", &speed); /* * At this point, it is planned to add an OF timeout property. * As soon as there is a consensus about how to call and handle * this, sth. like the following can be put here: * * of_property_read_u32(pdev->dev.of_node, "timeout", * &alg_data->timeout); */ } #endif alg_data->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(alg_data->clk)) return PTR_ERR(alg_data->clk); init_timer(&alg_data->mif.timer); alg_data->mif.timer.function = i2c_pnx_timeout; alg_data->mif.timer.data = (unsigned long)alg_data; snprintf(alg_data->adapter.name, sizeof(alg_data->adapter.name), "%s", pdev->name); /* Register I/O resource */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); alg_data->ioaddr = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(alg_data->ioaddr)) return PTR_ERR(alg_data->ioaddr); ret = clk_prepare_enable(alg_data->clk); if (ret) return ret; freq = clk_get_rate(alg_data->clk); /* * Clock Divisor High This value is the number of system clocks * the serial clock (SCL) will be high. * For example, if the system clock period is 50 ns and the maximum * desired serial period is 10000 ns (100 kHz), then CLKHI would be * set to 0.5*(f_sys/f_i2c)-2=0.5*(20e6/100e3)-2=98. The actual value * programmed into CLKHI will vary from this slightly due to * variations in the output pad's rise and fall times as well as * the deglitching filter length. */ tmp = (freq / speed) / 2 - 2; if (tmp > 0x3FF) tmp = 0x3FF; iowrite32(tmp, I2C_REG_CKH(alg_data)); iowrite32(tmp, I2C_REG_CKL(alg_data)); iowrite32(mcntrl_reset, I2C_REG_CTL(alg_data)); if (wait_reset(alg_data)) { ret = -ENODEV; goto out_clock; } init_completion(&alg_data->mif.complete); alg_data->irq = platform_get_irq(pdev, 0); if (alg_data->irq < 0) { dev_err(&pdev->dev, "Failed to get IRQ from platform resource\n"); ret = alg_data->irq; goto out_clock; } ret = devm_request_irq(&pdev->dev, alg_data->irq, i2c_pnx_interrupt, 0, pdev->name, alg_data); if (ret) goto out_clock; /* Register this adapter with the I2C subsystem */ ret = i2c_add_numbered_adapter(&alg_data->adapter); if (ret < 0) { dev_err(&pdev->dev, "I2C: Failed to add bus\n"); goto out_clock; } dev_dbg(&pdev->dev, "%s: Master at %#8x, irq %d.\n", alg_data->adapter.name, res->start, alg_data->irq); return 0; out_clock: clk_disable_unprepare(alg_data->clk); return ret; }
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", __func__); 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\n", 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_mem_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_mem_region(alg_data->base, I2C_PNX_REGION_SIZE); out_drvdata: platform_set_drvdata(pdev, NULL); out: return ret; }
static int __devinit i2c_pnx_probe(struct platform_device *pdev) { unsigned long tmp; int ret = 0; struct i2c_pnx_algo_data *alg_data; unsigned long freq; struct i2c_pnx_data *i2c_pnx = pdev->dev.platform_data; if (!i2c_pnx || !i2c_pnx->name) { dev_err(&pdev->dev, "%s: no platform data supplied\n", __func__); ret = -EINVAL; goto out; } alg_data = kzalloc(sizeof(*alg_data), GFP_KERNEL); if (!alg_data) { ret = -ENOMEM; goto err_kzalloc; } platform_set_drvdata(pdev, alg_data); strlcpy(alg_data->adapter.name, i2c_pnx->name, sizeof(alg_data->adapter.name)); alg_data->adapter.dev.parent = &pdev->dev; alg_data->adapter.algo = &pnx_algorithm; alg_data->adapter.algo_data = alg_data; alg_data->adapter.nr = pdev->id; alg_data->i2c_pnx = i2c_pnx; alg_data->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(alg_data->clk)) { ret = PTR_ERR(alg_data->clk); goto out_drvdata; } init_timer(&alg_data->mif.timer); alg_data->mif.timer.function = i2c_pnx_timeout; alg_data->mif.timer.data = (unsigned long)alg_data; /* Register I/O resource */ if (!request_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE, pdev->name)) { dev_err(&pdev->dev, "I/O region 0x%08x for I2C already in use.\n", i2c_pnx->base); ret = -ENODEV; goto out_clkget; } alg_data->ioaddr = ioremap(i2c_pnx->base, I2C_PNX_REGION_SIZE); if (!alg_data->ioaddr) { dev_err(&pdev->dev, "Couldn't ioremap I2C I/O region\n"); ret = -ENOMEM; goto out_release; } ret = clk_enable(alg_data->clk); if (ret) goto out_unmap; freq = clk_get_rate(alg_data->clk); /* * Clock Divisor High This value is the number of system clocks * the serial clock (SCL) will be high. * For example, if the system clock period is 50 ns and the maximum * desired serial period is 10000 ns (100 kHz), then CLKHI would be * set to 0.5*(f_sys/f_i2c)-2=0.5*(20e6/100e3)-2=98. The actual value * programmed into CLKHI will vary from this slightly due to * variations in the output pad's rise and fall times as well as * the deglitching filter length. */ tmp = ((freq / 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_clock; } init_completion(&alg_data->mif.complete); ret = request_irq(i2c_pnx->irq, i2c_pnx_interrupt, 0, pdev->name, alg_data); if (ret) goto out_clock; /* Register this adapter with the I2C subsystem */ ret = i2c_add_numbered_adapter(&alg_data->adapter); if (ret < 0) { dev_err(&pdev->dev, "I2C: Failed to add bus\n"); goto out_irq; } dev_dbg(&pdev->dev, "%s: Master at %#8x, irq %d.\n", alg_data->adapter.name, i2c_pnx->base, i2c_pnx->irq); return 0; out_irq: free_irq(i2c_pnx->irq, alg_data); out_clock: clk_disable(alg_data->clk); out_unmap: iounmap(alg_data->ioaddr); out_release: release_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE); out_clkget: clk_put(alg_data->clk); out_drvdata: kfree(alg_data); err_kzalloc: platform_set_drvdata(pdev, NULL); out: return ret; }
static int __devinit i2c_pnx_probe(struct platform_device *pdev) { unsigned long tmp; int ret = 0; struct i2c_pnx_algo_data *alg_data; unsigned long freq; struct i2c_pnx_data *i2c_pnx = pdev->dev.platform_data; if (!i2c_pnx || !i2c_pnx->name) { dev_err(&pdev->dev, "%s: no platform data supplied\n", __func__); ret = -EINVAL; goto out; } alg_data = kzalloc(sizeof(*alg_data), GFP_KERNEL); if (!alg_data) { ret = -ENOMEM; goto err_kzalloc; } platform_set_drvdata(pdev, alg_data); strlcpy(alg_data->adapter.name, i2c_pnx->name, sizeof(alg_data->adapter.name)); alg_data->adapter.dev.parent = &pdev->dev; alg_data->adapter.algo = &pnx_algorithm; alg_data->adapter.algo_data = alg_data; alg_data->adapter.nr = pdev->id; alg_data->i2c_pnx = i2c_pnx; alg_data->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(alg_data->clk)) { ret = PTR_ERR(alg_data->clk); goto out_drvdata; } init_timer(&alg_data->mif.timer); alg_data->mif.timer.function = i2c_pnx_timeout; alg_data->mif.timer.data = (unsigned long)alg_data; /* */ if (!request_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE, pdev->name)) { dev_err(&pdev->dev, "I/O region 0x%08x for I2C already in use.\n", i2c_pnx->base); ret = -ENODEV; goto out_clkget; } alg_data->ioaddr = ioremap(i2c_pnx->base, I2C_PNX_REGION_SIZE); if (!alg_data->ioaddr) { dev_err(&pdev->dev, "Couldn't ioremap I2C I/O region\n"); ret = -ENOMEM; goto out_release; } ret = clk_enable(alg_data->clk); if (ret) goto out_unmap; freq = clk_get_rate(alg_data->clk); /* */ tmp = ((freq / 1000) / I2C_PNX_SPEED_KHZ) / 2 - 2; if (tmp > 0x3FF) tmp = 0x3FF; iowrite32(tmp, I2C_REG_CKH(alg_data)); iowrite32(tmp, I2C_REG_CKL(alg_data)); iowrite32(mcntrl_reset, I2C_REG_CTL(alg_data)); if (wait_reset(I2C_PNX_TIMEOUT, alg_data)) { ret = -ENODEV; goto out_clock; } init_completion(&alg_data->mif.complete); ret = request_irq(i2c_pnx->irq, i2c_pnx_interrupt, 0, pdev->name, alg_data); if (ret) goto out_clock; /* */ ret = i2c_add_numbered_adapter(&alg_data->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", alg_data->adapter.name, i2c_pnx->base, i2c_pnx->irq); return 0; out_irq: free_irq(i2c_pnx->irq, alg_data); out_clock: clk_disable(alg_data->clk); out_unmap: iounmap(alg_data->ioaddr); out_release: release_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE); out_clkget: clk_put(alg_data->clk); out_drvdata: kfree(alg_data); err_kzalloc: platform_set_drvdata(pdev, NULL); out: return ret; }
bool probe_hardware( int minor ) { int erc, trans; byte rx_buffer[256]; int port = base_address[minor]; int irq = pclta_interrupt[minor]; struct pclta_device * device; if( !port || !irq ) return 0; VERBOSE_MSG( "probing minor = %d, I/O = %#x-%#x, interrupt request = %d ... ", minor, port, port+3, irq ); if( 0 > check_region( port, 4 ) ) { VERBOSE_MSG( "error(%d) PCLTA_IOPERM.\n", PCLTA_IOPERM ); return false; } init_hw( port, 0x00, CLK_10 ); // initialize device hardware, no IRQ if( ! wait_reset( port, 500 ) ) { VERBOSE_MSG( "error(%d) PCLTA_LRESET.\n", PCLTA_LRESET ); return false; } // waiting to leave reset state setup_timeout( 200 ); while( !pclta_timeout ); // Why wait? Because, when PCLTA gets out of RESET state, it sets // status register BEFORE preparing uplink reset. So, I read the // packet of length 0 and get an error. Stupid! // wait for reset command response if( ! wait_uplink_buffer( port, 500, rx_buffer ) ) { VERBOSE_MSG( "error(%d) PCLTA_RESP. \n", PCLTA_RESP ); return false; } // make sure the reset was successful if( rx_buffer[0] != 1 || rx_buffer[1] != niRESET ) { VERBOSE_MSG( "error(%d) PCLTA_RESP. Reset not successfull. \n", PCLTA_RESP ); return false; } // set up internal interrupt register write_byte_wait( port, CMD_XFER ); write_byte_wait( port, 2 ); write_byte_wait( port, niIRQENA ); write_byte_wait( port, IRQPLRTY | RESET_ENABLE | DLREADY_ENABLE | DLPBA_ENABLE | DLBA_ENABLE | ULREADY_ENABLE ); // write a command to get transciever status write_byte_wait( port, CMD_XFER ); write_byte_wait( port, 1 ); write_byte_wait( port, niSSTATUS ); // wait for response if( ! wait_uplink_buffer( port, 500, rx_buffer ) ) { VERBOSE_MSG( "error(%d) PCLTA_STAT.\n", PCLTA_STAT ); return false; } // get transceiver type trans = rx_buffer[2]>>3; if( ! *pclta_transceiver[trans] ) { VERBOSE_MSG( "error(%d) PCLTA_TSCV.\n", PCLTA_TSCV ); return false; // transciever not supported } // register character device if( 0 > (pclta_major = register_chrdev( 0, "pclta", &pclta_fops )) ) { VERBOSE_MSG( "error(%d) PCLTA_MAJOR.\n", PCLTA_MAJOR ); return false; } // request interrupt permission OLD LOCATION // if( 0 > ( erc = request_irq( irq, pclta_interrupt, 0, "pclta", NULL ) ) ) { SLOW INT // if( 0 > ( erc = request_irq( irq, pclta_interrupt,SA_INTERRUPT, "pclta", device ) ) ) { // VERBOSE_MSG( "error(%d) PCLTA_IRQPERM.\n", PCLTA_IRQPERM ); // return false; // } // create device descriptor device = create_device( port, irq, pclta_clock[rx_buffer[2]>>3] ); if( device == NULL ) { VERBOSE_MSG( "error(%d) PCLTA_CDEV.\n", PCLTA_CDEV ); return false; } // request interrupt permission NEW LOCATION SO WE HAVE DEVICE STRUCT // if( 0 > ( erc = request_irq( irq, pclta_interrupt, 0, "pclta", NULL ) ) ) { SLOW INT if( 0 > ( erc = request_irq( irq, pclta_interrupt_handler,0, "pclta", device) ) ) { VERBOSE_MSG( "error(%d) PCLTA_IRQPERM.\n", PCLTA_IRQPERM ); return false; } // set up pointers to device descriptor pclta_device_table[minor] = device; pclta_interrupt_table[minor] = device; // remember minor number device->minor = minor; // claim I/O space request_region( port, 4, "pclta" ); // start up the interupts removed 07/07 by karl. // init_hw( port,irq_mask[irq], CLK_10 ); // initialize device hardware, no IRQ DEBUG_MSG( "Transceiver type: %s", pclta_transceiver[trans] ); MESSAGE("Device pclta%d installed.", minor ); return true; }