示例#1
0
int  md_probe (struct md *md, int slot, struct mon *mon)
{
	struct cdev *cdev;
	dev_t dev_id;
	int ret;
	struct class *bmi_class;

	md->removed = 0;

	cdev = &md->cdev;
	cdev_init (cdev, &md_fops);

	dev_id = MKDEV (md_major, slot); 
	ret = cdev_add (cdev, dev_id, 1);

	//Create class device 
	bmi_class = bmi_get_class ();                            

	md->class_dev = device_create (bmi_class, NULL, MKDEV(md_major, slot), md, "bmi_mdacc_mot_m%i", slot);  
								     
	if (IS_ERR(md->class_dev)) {                                
		printk(KERN_ERR "Unable to create "                  
		       "class_device for bmi_mdacc_mot_m%i; errno = %ld\n",
		       slot, PTR_ERR(md->class_dev));             
		md->class_dev = NULL;                               
	}

	md->open_flag = 0;
	md->enabled = 0;
	md->status = 0;
	init_waitqueue_head (&md->read_wait_queue);
	md->mon = mon;
	return ret;
}
示例#2
0
int  acc_probe (struct acc *acc, int slot, struct mon *mon)
{
    struct cdev *cdev;
    dev_t dev_id;
    int ret;
    struct class *bmi_class;

    // initialize cdev

    cdev = &acc->cdev;
    cdev_init (cdev, &acc_fops);

    dev_id = MKDEV (acc_major, slot);
    ret = cdev_add (cdev, dev_id, 1);

    //Create class device

    bmi_class = bmi_get_class ();

    acc->class_dev = device_create (bmi_class, NULL, MKDEV(acc_major, slot), acc, "bmi_mdacc_acc_m%i", slot);

    if (IS_ERR(acc->class_dev)) {
        printk(KERN_ERR "Unable to create "
               "class_device for bmi_mdacc_acc_m%i; errno = %ld\n",
               slot, PTR_ERR(acc->class_dev));
        acc->class_dev = NULL;
    }

    acc->open_flag = 0;
    acc->mon = mon;


    // initialize mdacc_accel_config

    acc->cfg.read_queue_size = 1;
    acc->cfg.read_queue_threshold = 1;
    acc->cfg.delay_mode = 0;
    acc->cfg.delay = 4000;
    acc->cfg.delay_resolution = 1;
    acc->cfg.sensitivity = 0;
    acc->cfg.run = 0;


    // initialize cque

    acc->cque = cque_create  (acc->cfg.read_queue_size, acc->cfg.read_queue_threshold);

    // initialize read_wait_queue

    init_waitqueue_head (&acc->read_wait_queue);
    return ret;
}
示例#3
0
void md_remove (struct md *md, int slot )
{
	struct class *bmi_class;

	md->removed = 1;
	md->ready = -1;
	wake_up_interruptible (&md->read_wait_queue);

	cdev_del (&md->cdev);
	bmi_class = bmi_get_class ();
	device_destroy (bmi_class, MKDEV(md_major, slot));
	md->class_dev = 0;
	return;
}
示例#4
0
void acc_remove (struct acc *acc, int slot)
{
    struct class *bmi_class;

    cque_destroy (acc->cque);

    bmi_class = bmi_get_class ();
    device_destroy (bmi_class, MKDEV(acc_major, slot));

    acc->class_dev = 0;

    cdev_del (&acc->cdev);


    return;
}
示例#5
0
/* 
 * 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
}
示例#6
0
// 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;
}