Пример #1
0
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);
	}
}
Пример #2
0
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);
	}
}
Пример #3
0
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;
}
Пример #4
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);
}
Пример #5
0
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;
}
Пример #6
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",
		       __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;
}
Пример #7
0
static int __devinit i2c_pnx_probe(struct platform_device *pdev)
{
	unsigned long tmp;
	int ret = 0;
	struct i2c_pnx_algo_data *alg_data;
	unsigned long freq;
	struct 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;
}
Пример #8
0
static int __devinit i2c_pnx_probe(struct platform_device *pdev)
{
	unsigned long tmp;
	int ret = 0;
	struct i2c_pnx_algo_data *alg_data;
	unsigned long freq;
	struct 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;
}
Пример #9
0
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;
}