Example #1
0
static int open_display(struct omap_display_device *display,
	enum omap_display_feature features)
{
	int i;

	DBG_PRINT("Opening display '%s'", display->name);

	/* TODO: Support horizontal orientation */
	if (features & ORIENTATION_HORIZONTAL) {
		DBG_PRINT("Horizontal orientation is not supported yet , "
			"falling back to vertical orientation");
		features = ORIENTATION_VERTICAL;
	}

	display->features = features;
	display->reference_count++;
	for (i = 0; i < display->overlay_managers_count; i++)
		omap_dss_get_device(display->overlay_managers[i]->device);

	/* If the main buffer doesn't exist create it */
	if (!display->main_buffer) {
		DBG_PRINT("Main buffer doesn't exist for display '%s', create"
			" one", display->name);
		display->main_buffer = create_main_buffer(display);
		if (!display->main_buffer) {
			ERR_PRINT("Failed to create main buffer for '%s'",
				display->name);
			return 1;
		}
	}

	return 0;
}
/* initialize connector */
struct drm_connector *omap_connector_init(struct drm_device *dev,
		int connector_type, struct omap_dss_device *dssdev,
		struct drm_encoder *encoder)
{
	struct drm_connector *connector = NULL;
	struct omap_connector *omap_connector;

	DBG("%s", dssdev->name);

	omap_dss_get_device(dssdev);

	omap_connector = kzalloc(sizeof(struct omap_connector), GFP_KERNEL);
	if (!omap_connector) {
		dev_err(dev->dev, "could not allocate connector\n");
		goto fail;
	}

	omap_connector->dssdev = dssdev;
	omap_connector->encoder = encoder;

	connector = &omap_connector->base;

	drm_connector_init(dev, connector, &omap_connector_funcs,
				connector_type);
	drm_connector_helper_add(connector, &omap_connector_helper_funcs);

#if 0 /* enable when dss2 supports hotplug */
	if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_HPD)
		connector->polled = 0;
	else
#endif
		connector->polled = DRM_CONNECTOR_POLL_CONNECT |
				DRM_CONNECTOR_POLL_DISCONNECT;

	connector->interlace_allowed = 1;
	connector->doublescan_allowed = 0;

	drm_sysfs_connector_add(connector);

	return connector;

fail:
	if (connector)
		omap_connector_destroy(connector);

	return NULL;
}
Example #3
0
/*
 * ref count of the found device is incremented.
 * ref count of from-device is decremented.
 */
struct omap_dss_device *omap_dss_get_next_device(struct omap_dss_device *from)
{
	struct list_head *l;
	struct omap_dss_device *dssdev;

	mutex_lock(&panel_list_mutex);

	if (list_empty(&panel_list)) {
		dssdev = NULL;
		goto out;
	}

	if (from == NULL) {
		dssdev = list_first_entry(&panel_list, struct omap_dss_device,
				panel_list);
		omap_dss_get_device(dssdev);
		goto out;
	}
Example #4
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
}
Example #5
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;
}
Example #6
0
static __devinit int omap_hdmi_probe(struct platform_device *pdev)
{
    int ret;
    struct resource *hdmi_rsrc;
    struct omap_dss_device *dssdev = NULL;
    bool hdmi_dev_found = false;

    hdmi_rsrc = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    if (!hdmi_rsrc) {
        dev_err(&pdev->dev, "Cannot obtain IORESOURCE_MEM HDMI\n");
        return -ENODEV;
    }

    omap_hdmi_dai_dma_params.port_addr =  hdmi_rsrc->start
                                          + OMAP_HDMI_AUDIO_DMA_PORT;

    hdmi_rsrc = platform_get_resource(pdev, IORESOURCE_DMA, 0);
    if (!hdmi_rsrc) {
        dev_err(&pdev->dev, "Cannot obtain IORESOURCE_DMA HDMI\n");
        return -ENODEV;
    }

    hdmi.oh = omap_hwmod_lookup("dss_hdmi");
    if (!hdmi.oh) {
        dev_err(&pdev->dev, "can't find omap_hwmod for hdmi\n");
        return -ENODEV;
    }

    omap_hdmi_dai_dma_params.dma_req =  hdmi_rsrc->start;

    /*
     * Find an HDMI device. In the future, registers all the HDMI devices
     * it finds and create a PCM for each.
     */
    for_each_dss_dev(dssdev) {
        omap_dss_get_device(dssdev);

        if (!dssdev->driver) {
            omap_dss_put_device(dssdev);
            continue;
        }

        if (dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
            hdmi_dev_found = true;
            break;
        }
    }

    if (!hdmi_dev_found) {
        dev_err(&pdev->dev, "no driver for HDMI display found");
        return -ENODEV;
    }

    hdmi.dssdev = dssdev;

    /* the supported rates and sample format depend on the cpu */
    if (cpu_is_omap44xx()) {
        omap_hdmi_dai.playback.rates = OMAP4_HDMI_RATES;
        omap_hdmi_dai.playback.formats = OMAP4_HDMI_FORMATS;
        omap_hdmi_dai.playback.channels_max	= 8;
    } else { /* OMAP5 */
        omap_hdmi_dai.playback.rates = OMAP5_HDMI_RATES;
        omap_hdmi_dai.playback.formats = OMAP5_HDMI_FORMATS;
#ifdef CONFIG_ARCH_OMAP5_ES1
        omap_hdmi_dai.playback.channels_max	= 2;
#else
        omap_hdmi_dai.playback.channels_max	= 8;
#endif
    }
    ret = snd_soc_register_dai(&pdev->dev, &omap_hdmi_dai);

    hdmi.notifier.notifier_call = hdmi_audio_notifier_callback;
    blocking_notifier_chain_register(&hdmi.dssdev->state_notifiers,
                                     &hdmi.notifier);

    return ret;
}