/* These flags can be used for the canchip_t structure flags data entry */
-#define CHIP_CONFIGURED (1<<0) /* chip is configured and prepared for communication */
-#define CHIP_SEGMENTED (1<<1) /* segmented access, ex: i82527 with 16 byte window*/
-#define CHIP_IRQ_SETUP (1<<2) /* IRQ handler has been set */
-#define CHIP_IRQ_PCI (1<<3) /* chip is on PCI board and uses PCI interrupt */
-#define CHIP_IRQ_VME (1<<4) /* interrupt is VME bus and requires VME bridge */
-#define CHIP_IRQ_CUSTOM (1<<5) /* custom interrupt provided by board or chip code */
-#define CHIP_IRQ_FAST (1<<6) /* interrupt handler only schedules postponed processing */
+#define CHIP_ATTACHED (1<<0) /* chip is attached to HW, release_chip() has to be called */
+#define CHIP_CONFIGURED (1<<1) /* chip is configured and prepared for communication */
+#define CHIP_SEGMENTED (1<<2) /* segmented access, ex: i82527 with 16 byte window*/
+#define CHIP_IRQ_SETUP (1<<3) /* IRQ handler has been set */
+#define CHIP_IRQ_PCI (1<<4) /* chip is on PCI board and uses PCI interrupt */
+#define CHIP_IRQ_VME (1<<5) /* interrupt is VME bus and requires VME bridge */
+#define CHIP_IRQ_CUSTOM (1<<6) /* custom interrupt provided by board or chip code */
+#define CHIP_IRQ_FAST (1<<7) /* interrupt handler only schedules postponed processing */
#define CHIP_MAX_IRQLOOP 1000
* @enable_configuration: enable chip configuration mode
* @disable_configuration: disable chip configuration mode
* @set_btregs: configures bitrate registers
+ * @attach_to_chip: attaches to the chip, setups registers and possibly state informations
+ * @release_chip: called before chip structure removal if %CHIP_ATTACHED is set
* @start_chip: starts chip message processing
* @stop_chip: stops chip message processing
* @irq_handler: interrupt service routine
int (*disable_configuration)(struct canchip_t *chip);
int (*set_btregs)(struct canchip_t *chip, unsigned short btr0,
unsigned short btr1);
+ int (*attach_to_chip)(struct canchip_t *chip);
+ int (*release_chip)(struct canchip_t *chip);
int (*start_chip)(struct canchip_t *chip);
int (*stop_chip)(struct canchip_t *chip);
int (*irq_handler)(int irq, struct canchip_t *chip);
return 0;
}
+int c_can_attach_to_chip(struct canchip_t *chip)
+{
+ return 0;
+}
+
+int c_can_release_chip(struct canchip_t *chip)
+{
+ int temp;
+
+ temp = c_can_read_reg_w(chip, CCCR);
+
+ /* Disable IRQ generation */
+ c_can_config_irqs(chip, 0);
+
+ temp = c_can_read_reg_w(chip, CCCR);
+
+ /* Power-down C_CAN, except this does nothing in the version 1.2 */
+ c_can_stop_chip(chip);
+
+
+ return 0;
+}
+
///////////////////////////////////////////////////////////////////////
/*
*Check the TxOK bit of the Status Register and resets it afterwards.
chipspecops->remote_request=c_can_remote_request;
chipspecops->enable_configuration=c_can_enable_configuration;
chipspecops->disable_configuration=c_can_disable_configuration;
+ chipspecops->attach_to_chip=c_can_attach_to_chip;
+ chipspecops->release_chip=c_can_release_chip;
chipspecops->set_btregs=c_can_set_btregs;
chipspecops->start_chip=c_can_start_chip;
chipspecops->stop_chip=c_can_stop_chip;
int i;
struct msgobj_t *obj;
+ if(chip->flags & CHIP_ATTACHED)
+ chip->chipspecops->release_chip(chip);
+
if((chip->hostdevice) && (chip->chip_idx>=0)) {
if(chip->hostdevice->chip[chip->chip_idx] == chip)
chip->hostdevice->chip[chip->chip_idx] = NULL;
return 0;
}
+int i82527_attach_to_chip(struct canchip_t *chip)
+{
+ return 0;
+}
+
+int i82527_release_chip(struct canchip_t *chip)
+{
+ i82527_stop_chip(chip);
+ can_write_reg(chip, (iCTL_CCE|iCTL_INI), iCTL);
+
+ return 0;
+}
+
static inline
void i82527_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj)
{
chipspecops->enable_configuration = i82527_enable_configuration;
chipspecops->disable_configuration = i82527_disable_configuration;
chipspecops->set_btregs = i82527_set_btregs;
+ chipspecops->attach_to_chip = i82527_attach_to_chip;
+ chipspecops->release_chip = i82527_release_chip;
chipspecops->start_chip = i82527_start_chip;
chipspecops->stop_chip = i82527_stop_chip;
chipspecops->irq_handler = i82527_irq_handler;
for(j=0; j<candev->nr_all_chips; j++) {
if((chip=candev->chip[j])==NULL)
continue;
+
+ if(chip->chipspecops->attach_to_chip(chip)<0) {
+ CANMSG("Initial attach to the chip HW failed\n");
+ goto interrupt_error;
+ }
+
+ chip->flags |= CHIP_ATTACHED;
+
if(can_chip_setup_irq(chip)<0) {
- CANMSG("IRQ setup failed\n");
+ CANMSG("Error to setup chip IRQ\n");
goto interrupt_error;
}
}
-
+
if (candev->flags & CANDEV_PROGRAMMABLE_IRQ)
- if (candev->hwspecops->program_irq(candev))
+ if (candev->hwspecops->program_irq(candev)){
+ CANMSG("Error to program board interrupt\n");
goto interrupt_error;
+ }
}
#ifdef CONFIG_PROC_FS
#endif
interrupt_error: ;
- CANMSG("Error registering interrupt line.\n");
goto memory_error;
reset_error: ;
return 0;
}
+int sja1000_attach_to_chip(struct canchip_t *chip)
+{
+ return 0;
+}
+
+int sja1000_release_chip(struct canchip_t *chip)
+{
+ sja1000_stop_chip(chip);
+ can_write_reg(chip,sjaCR_RR,SJACR);
+
+ return 0;
+}
+
int sja1000_remote_request(struct canchip_t *chip, struct msgobj_t *obj)
{
CANMSG("sja1000_remote_request not implemented\n");
chipspecops->enable_configuration = sja1000_enable_configuration;
chipspecops->disable_configuration = sja1000_disable_configuration;
chipspecops->set_btregs = sja1000_set_btregs;
+ chipspecops->attach_to_chip=sja1000_attach_to_chip;
+ chipspecops->release_chip=sja1000_release_chip;
chipspecops->start_chip = sja1000_start_chip;
chipspecops->stop_chip = sja1000_stop_chip;
chipspecops->irq_handler = sja1000_irq_handler;
return 0;
}
+/**
+ * sja1000p_attach_to_chip: - attaches to the chip, setups registers and state
+ * @chip: pointer to chip state structure
+ *
+ * Return Value: negative value reports error.
+ * File: src/sja1000p.c
+ */
+int sja1000p_attach_to_chip(struct canchip_t *chip)
+{
+ return 0;
+}
+
+/**
+ * sja1000p_release_chip: - called before chip structure removal if %CHIP_ATTACHED is set
+ * @chip: pointer to chip state structure
+ *
+ * Return Value: negative value reports error.
+ * File: src/sja1000p.c
+ */
+int sja1000p_release_chip(struct canchip_t *chip)
+{
+ sja1000p_stop_chip(chip);
+ can_write_reg(chip, sjaDISABLE_INTERRUPTS, SJAIER);
+
+ return 0;
+}
/**
* sja1000p_remote_request: - configures message object and asks for RTR message
chipspecops->remote_request=sja1000p_remote_request;
chipspecops->enable_configuration=sja1000p_enable_configuration;
chipspecops->disable_configuration=sja1000p_disable_configuration;
+ chipspecops->attach_to_chip=sja1000p_attach_to_chip;
+ chipspecops->release_chip=sja1000p_release_chip;
chipspecops->set_btregs=sja1000p_set_btregs;
chipspecops->start_chip=sja1000p_start_chip;
chipspecops->stop_chip=sja1000p_stop_chip;
return 0;
}
+/**
+ * unican_attach_to_chip: - attaches to the chip, setups registers and state
+ * @chip: pointer to chip state structure
+ *
+ * Return Value: negative value reports error.
+ * File: src/sja1000p.c
+ */
+int unican_attach_to_chip(struct canchip_t *chip)
+{
+ return 0;
+}
+
+/**
+ * unican_release_chip: - called before chip structure removal if %CHIP_ATTACHED is set
+ * @chip: pointer to chip state structure
+ *
+ * Return Value: negative value reports error.
+ * File: src/sja1000p.c
+ */
+int unican_release_chip(struct canchip_t *chip)
+{
+ sCAN_CARD *chipext = (sCAN_CARD *)chip->chip_data;
+
+ unican_stop_chip(chip);
+ cl2_clear_interrupt(chipext);
+
+ return 0;
+}
/**
* unican_remote_request: - configures message object and asks for RTR message
chip->chipspecops->enable_configuration=unican_enable_configuration;
chip->chipspecops->disable_configuration=unican_disable_configuration;
chip->chipspecops->set_btregs=unican_set_btregs;
+ chip->chipspecops->attach_to_chip=unican_attach_to_chip;
+ chip->chipspecops->release_chip=unican_release_chip;
chip->chipspecops->start_chip=unican_start_chip;
chip->chipspecops->stop_chip=unican_stop_chip;
chip->chipspecops->irq_handler=unican_irq_handler;