int bmi_li3m02cm_probe(struct bmi_device *bdev) { struct bmi_li3m02cm *cam; int ret=0; cam = kzalloc(sizeof(*cam), GFP_KERNEL); if (!cam) return -1; bmi_device_set_drvdata(bdev, cam); cam->bdev = bdev; cam->iox = i2c_new_device(bdev->slot->adap, &iox_info); cam->mt9t111 = i2c_new_device(bdev->slot->adap, &mt9t111_info); configure_GPIO(cam); // configure GPIO and IOX configure_IOX(cam); //register this as a bug_camera bmi_register_camera(bdev, &li3m02cm_ops, &li3m02cm_bmi_ops,THIS_MODULE); // These can be removed after driver stabalizes. They are for debug now. ret = device_create_file(&bdev->dev, &dev_attr_gpio_value); ret = device_create_file(&bdev->dev, &dev_attr_iox_value); ret = device_create_file(&bdev->dev, &dev_attr_iox_addr); ret = device_create_file(&bdev->dev, &dev_attr_mt9t111_value); ret = device_create_file(&bdev->dev, &dev_attr_mt9t111_addr); ret = device_create_file(&bdev->dev, &dev_attr_set_power); ret = device_create_file(&bdev->dev, &dev_attr_format); ret = device_create_file(&bdev->dev, &dev_attr_context); return ret; }
/* * Function is called when the video module hardwrae is physically removed */ void bmi_video_remove(struct bmi_device *bdev) { int irq; int i; int slot; struct bmi_video *video; struct class *bmi_class; static struct omap_dss_device *dssdev; printk(KERN_DEBUG "bmi_video: Module Removed...\n"); //Would turn LED red, but we can't trust the HW is connected still slot = bdev->slot->slotnum; video = &g_bmi_video; //removals have known unwind errors iff rmmod bmi_video_core while //device is plugged in device_remove_file(&bdev->dev, &dev_attr_vmode); device_remove_file(&bdev->dev, &dev_attr_vga_edid); device_remove_file(&bdev->dev, &dev_attr_dvi_edid); bmi_class = bmi_get_class (); device_destroy (bmi_class, MKDEV(major, slot)); // -- disable displays monitors_off_safe(video);//safe for missing HW // -- disable all displays for_each_dss_dev(dssdev) { omap_dss_get_device(dssdev); if (dssdev->state) dssdev->driver->disable(dssdev); } if(video->swap_eeprom){ //we are just 'borrowing' this pointer, //do not unregister! see bmi_video_probe. video->swap_eeprom = NULL; video->swap_eeprom_state = OFF; } if(video->eeprom_switch) { i2c_unregister_device(video->eeprom_switch); video->eeprom_switch = NULL; } if(video->gpio_controller) { //dbg_unexport_gpios_to_sysfs(); gpio_free_array(vid_gpios, ARRAY_SIZE(vid_gpios)); i2c_unregister_device(video->gpio_controller); video->gpio_controller= NULL; } if(video->dvi_controller) { i2c_unregister_device(video->dvi_controller); video->dvi_controller = NULL; } printk(KERN_INFO "bmi_video: 9\n"); if(video->vga_controller) { i2c_unregister_device(video->vga_controller); video->vga_controller = NULL; } irq = bdev->slot->status_irq; // -- legacy vodoo code. Left in for safety for (i = 0; i < 4; i++) bmi_slot_gpio_direction_in(slot, i); if (video->vga_monitor_edid) { kfree(video->vga_monitor_edid); //created by a library. we must free video->vga_monitor_edid = NULL; } if (video->dvi_monitor_edid) { kfree(video->dvi_monitor_edid); //created by a library. we must free video->dvi_monitor_edid = NULL; } //just in case, clear the global g_dvi_disp = NULL; g_vga_disp = NULL; video->class_dev = 0; // de-attach driver-specific struct from bmi_device structure bmi_device_set_drvdata (bdev, 0); video->bdev = 0; printk(KERN_INFO "bmi_video_remove done "); return; //Clean, squeaky clean }
// probe - insert PIM int bmi_video_probe(struct bmi_device *bdev) { int err = 0; int slot; int irq; struct bmi_video *video; struct class *bmi_class; struct i2c_adapter *adap; struct omap_dss_device *dssdev; printk (KERN_INFO "bmi_video.c: probe...\n"); slot = bdev->slot->slotnum; adap = bdev->slot->adap; video = &g_bmi_video; video->dvi_monitor_edid = NULL; video->vga_monitor_edid = NULL; video->bdev = 0; dssdev = NULL; g_dvi_disp = NULL; g_vga_disp = NULL; /* disable all video devices, store vga/dvi entries */ for_each_dss_dev(dssdev) { omap_dss_get_device(dssdev); if (dssdev->state) dssdev->driver->disable(dssdev); // our dss names are from buglabs board files if (strnicmp(dssdev->name, "dvi", 3) == 0) g_dvi_disp = dssdev; else if (strnicmp(dssdev->name, "vga", 3) == 0) g_vga_disp = dssdev; } // bind driver and bmi_device video->bdev = bdev; // create class device bmi_class = bmi_get_class(); // -- grab eeprom addr if(bdev->slot->eeprom) { video->swap_eeprom = bdev->slot->eeprom; video->swap_eeprom_state = OFF; //set to read bmi board eeprom //printk(KERN_ERR "swizzling slot eeprom, addr %x", // (unsigned int)video->swap_eeprom->addr); } else { printk(KERN_ERR "module eeprom is null. Module type is impossible"); video->swap_eeprom = 0x00; video->swap_eeprom_state = OFF; } // -- grap i2c expander switch video->eeprom_switch = i2c_new_device(adap, &i2cswitch_info); if(video->eeprom_switch == NULL) { printk(KERN_ERR "i2c addr %x fail", i2cswitch_info.addr); err = -ENOTTY; goto probe_fail1; } // -- grab i2c gpio chip and set it up if (gpio_is_valid(VIDEO_GPIO_BASE)) video->gpio_controller = i2c_new_device(adap,&gpio_controller_info); else { printk(KERN_ERR "i2c addr %x in use", VIDEO_GPIO_BASE); err = -ENOTTY; goto probe_fail2; } if(video->gpio_controller == NULL) { printk(KERN_ERR "i2c addr %x fail", gpio_controller_info.addr); err = -ENOTTY; goto probe_fail2; } err = gpio_request_array(vid_gpios, ARRAY_SIZE(vid_gpios)); if (err) { printk(KERN_ERR "GPIO's not requestable. Damm"); err = -ENOTTY; goto probe_fail3; } //dbg_export_gpios_to_sysfs(); //we have gpio's now, turn the LED to red since we are not initalized bmi_video_ledset(VIDEO_LED_RED); // -- grab i2c for the dvi controller video->dvi_controller = i2c_new_device(adap, &tfp_info); if (video->dvi_controller == NULL){ printk(KERN_ERR "DVI monitor controller not found\n"); err = -ENOTTY; goto probe_fail4; } video->vga_controller = i2c_new_device(adap, &ths_info); if (video->vga_controller == NULL) { printk(KERN_ERR "VGA monitor controller not found\n"); err = -ENOTTY; goto probe_fail5; } //FUTURE: enable pulg event interrupt for GPIO //ths_info.irq = gpio_to_irq(DVI_MONITOR_SENSE_GPIO); // -- to get ths8201 on the bus OK, we need to do a reset cycle ths8200_disable(video->vga_controller);//TRICKY: does some setup -> //didn't have time to debug why this works and 'init' doesn't ths8200_standby(VGA_RESET_GPIO); err = device_create_file(&bdev->dev, &dev_attr_vmode); if (err < 0) printk(KERN_ERR "Error creating SYSFS entries...\n"); //TRCIKY: don't exit on this error, tolerate it err = scan_for_monitors(AUTO, video); //based on monitor's found, choose the best' if(video->dvi_monitor_edid) { printk(KERN_INFO "dvi monitor detected"); enable_dvi(video); } else if(video->vga_monitor_edid) { printk(KERN_INFO "vga monitor detected"); enable_vga(video); } else { printk(KERN_ERR "no monitor detected"); monitors_off(video); } err = device_create_file(&bdev->dev, &dev_attr_vga_edid); if (err < 0) printk(KERN_ERR "Error creating SYSFS entries...\n"); //TRCIKY: don't exit on this error, tolerate it err = device_create_file(&bdev->dev, &dev_attr_dvi_edid); if (err < 0) printk(KERN_ERR "Error creating SYSFS entries...\n"); //TRCIKY: don't exit on this error, tolerate it //request PIM interrupt irq = bdev->slot->status_irq; sprintf (video->int_name, "bmi_video%d", slot); bmi_device_set_drvdata (bdev, video); // -- successfuly loaded, even if not everyting is perfect return 0; // -- failure/error cleanup probe_fail5: if(video->dvi_controller) { i2c_unregister_device(video->dvi_controller); video->dvi_controller = NULL; } probe_fail4: //dbg_unexport_gpios_to_sysfs(); probe_fail3: if(video->gpio_controller) { i2c_unregister_device(video->gpio_controller); video->gpio_controller = NULL; } probe_fail2: if(video->eeprom_switch) { i2c_unregister_device(video->eeprom_switch); video->eeprom_switch = NULL; } probe_fail1: video->swap_eeprom = 0x00; video->swap_eeprom_state = OFF; return err; }