aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/base/Kconfig2
-rw-r--r--drivers/base/firmware_class.c24
-rw-r--r--drivers/base/platform.c31
-rw-r--r--drivers/base/power/main.c7
-rw-r--r--drivers/char/Kconfig9
-rw-r--r--drivers/char/applicom.c2
-rw-r--r--drivers/char/ds1286.c4
-rw-r--r--drivers/char/hw_random/omap-rng.c33
-rw-r--r--drivers/char/keyboard.c2
-rw-r--r--drivers/char/moxa.c2
-rw-r--r--drivers/char/random.c2
-rw-r--r--drivers/char/rtc.c2
-rw-r--r--drivers/char/sysrq.c31
-rw-r--r--drivers/char/tpm/tpm.c36
-rw-r--r--drivers/char/vt.c2
-rw-r--r--drivers/edac/i5000_edac.c196
-rw-r--r--drivers/edac/i82443bxgx_edac.c63
-rw-r--r--drivers/edac/mpc85xx_edac.c33
-rw-r--r--drivers/gpio/gpiolib.c111
-rw-r--r--drivers/gpio/max7301.c24
-rw-r--r--drivers/gpio/max732x.c5
-rw-r--r--drivers/gpio/mcp23s08.c5
-rw-r--r--drivers/gpio/pca953x.c5
-rw-r--r--drivers/gpio/pcf857x.c5
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c4
-rw-r--r--drivers/hid/Kconfig122
-rw-r--r--drivers/hid/hid-core.c2
-rw-r--r--drivers/hid/hid-ids.h2
-rw-r--r--drivers/i2c/busses/i2c-omap.c12
-rw-r--r--drivers/ide/Kconfig2
-rw-r--r--drivers/input/gameport/gameport.c88
-rw-r--r--drivers/input/joystick/a3d.c3
-rw-r--r--drivers/input/joystick/adi.c3
-rw-r--r--drivers/input/joystick/analog.c4
-rw-r--r--drivers/input/joystick/cobra.c3
-rw-r--r--drivers/input/joystick/gf2k.c3
-rw-r--r--drivers/input/joystick/grip.c3
-rw-r--r--drivers/input/joystick/grip_mp.c3
-rw-r--r--drivers/input/joystick/guillemot.c3
-rw-r--r--drivers/input/joystick/interact.c3
-rw-r--r--drivers/input/joystick/joydump.c3
-rw-r--r--drivers/input/joystick/sidewinder.c3
-rw-r--r--drivers/input/joystick/tmdc.c3
-rw-r--r--drivers/input/joystick/xpad.c4
-rw-r--r--drivers/input/keyboard/atkbd.c30
-rw-r--r--drivers/input/keyboard/bf54x-keys.c13
-rw-r--r--drivers/input/keyboard/gpio_keys.c42
-rw-r--r--drivers/input/keyboard/omap-keypad.c29
-rw-r--r--drivers/input/misc/Kconfig13
-rw-r--r--drivers/input/misc/Makefile1
-rw-r--r--drivers/input/misc/ati_remote2.c263
-rw-r--r--drivers/input/misc/cm109.c882
-rw-r--r--drivers/input/misc/map_to_7segment.h189
-rw-r--r--drivers/input/misc/wistron_btns.c19
-rw-r--r--drivers/input/misc/yealink.c2
-rw-r--r--drivers/input/mouse/Kconfig10
-rw-r--r--drivers/input/mouse/Makefile1
-rw-r--r--drivers/input/mouse/alps.c1
-rw-r--r--drivers/input/mouse/appletouch.c299
-rw-r--r--drivers/input/mouse/hgpk.c477
-rw-r--r--drivers/input/mouse/hgpk.h49
-rw-r--r--drivers/input/mouse/logips2pp.c4
-rw-r--r--drivers/input/mouse/psmouse-base.c81
-rw-r--r--drivers/input/mouse/psmouse.h14
-rw-r--r--drivers/input/mouse/trackpoint.c8
-rw-r--r--drivers/input/serio/i8042-x86ia64io.h7
-rw-r--r--drivers/input/serio/serio_raw.c6
-rw-r--r--drivers/input/tablet/aiptek.c53
-rw-r--r--drivers/input/touchscreen/ads7846.c94
-rw-r--r--drivers/input/touchscreen/atmel_tsadcc.c37
-rw-r--r--drivers/input/touchscreen/mainstone-wm97xx.c5
-rw-r--r--drivers/input/touchscreen/wm9705.c5
-rw-r--r--drivers/input/touchscreen/wm9712.c5
-rw-r--r--drivers/input/touchscreen/wm9713.c5
-rw-r--r--drivers/input/touchscreen/wm97xx-core.c5
-rw-r--r--drivers/md/faulty.c2
-rw-r--r--drivers/md/linear.c133
-rw-r--r--drivers/md/md.c81
-rw-r--r--drivers/md/multipath.c9
-rw-r--r--drivers/md/raid0.c5
-rw-r--r--drivers/md/raid1.c1
-rw-r--r--drivers/md/raid10.c6
-rw-r--r--drivers/md/raid5.c42
-rw-r--r--drivers/md/raid6.h9
-rw-r--r--drivers/media/video/cpia.c4
-rw-r--r--drivers/media/video/usbvision/usbvision-core.c4
-rw-r--r--drivers/media/video/usbvision/usbvision-video.c4
-rw-r--r--drivers/media/video/v4l1-compat.c4
-rw-r--r--drivers/media/video/v4l2-common.c4
-rw-r--r--drivers/media/video/vino.c5
-rw-r--r--drivers/media/video/w9968cf.c4
-rw-r--r--drivers/message/i2o/Makefile2
-rw-r--r--drivers/message/i2o/device.c2
-rw-r--r--drivers/message/i2o/exec-osm.c4
-rw-r--r--drivers/message/i2o/i2o_config.c31
-rw-r--r--drivers/message/i2o/iop.c2
-rw-r--r--drivers/message/i2o/memory.c313
-rw-r--r--drivers/message/i2o/pci.c16
-rw-r--r--drivers/misc/Kconfig3
-rw-r--r--drivers/misc/hp-wmi.c2
-rw-r--r--drivers/misc/sgi-gru/gru.h4
-rw-r--r--drivers/misc/sgi-gru/gru_instructions.h10
-rw-r--r--drivers/misc/sgi-gru/grufault.c11
-rw-r--r--drivers/misc/sgi-gru/grufile.c8
-rw-r--r--drivers/misc/sgi-gru/gruhandles.h5
-rw-r--r--drivers/misc/sgi-gru/grukservices.c3
-rw-r--r--drivers/misc/sgi-gru/grumain.c29
-rw-r--r--drivers/mmc/host/omap.c11
-rw-r--r--drivers/mtd/mtdpart.c2
-rw-r--r--drivers/mtd/nand/ams-delta.c4
-rw-r--r--drivers/net/3c509.c2
-rw-r--r--drivers/net/cs89x0.c13
-rw-r--r--drivers/net/irda/sir_dongle.c2
-rw-r--r--drivers/net/ppp_generic.c10
-rw-r--r--drivers/net/pppox.c9
-rw-r--r--drivers/net/wireless/ath9k/main.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c2
-rw-r--r--drivers/net/wireless/libertas/cmd.c2
-rw-r--r--drivers/net/wireless/orinoco_cs.c5
-rw-r--r--drivers/net/wireless/p54/p54common.c1
-rw-r--r--drivers/net/wireless/p54/p54usb.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c9
-rw-r--r--drivers/net/wireless/rtl8187_dev.c3
-rw-r--r--drivers/net/wireless/spectrum_cs.c5
-rw-r--r--drivers/net/xen-netfront.c2
-rw-r--r--drivers/nubus/nubus.c2
-rw-r--r--drivers/parport/ChangeLog2
-rw-r--r--drivers/parport/ieee1284.c2
-rw-r--r--drivers/parport/probe.c2
-rw-r--r--drivers/parport/share.c2
-rw-r--r--drivers/pcmcia/Makefile3
-rw-r--r--drivers/pnp/base.h2
-rw-r--r--drivers/pnp/core.c1
-rw-r--r--drivers/pnp/quirks.c2
-rw-r--r--drivers/pnp/resource.c4
-rw-r--r--drivers/power/olpc_battery.c20
-rw-r--r--drivers/rtc/Kconfig25
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/rtc-at91rm9200.c4
-rw-r--r--drivers/rtc/rtc-dev.c12
-rw-r--r--drivers/rtc/rtc-ds1286.c1
-rw-r--r--drivers/rtc/rtc-ds1307.c308
-rw-r--r--drivers/rtc/rtc-ds1374.c21
-rw-r--r--drivers/rtc/rtc-ds1511.c13
-rw-r--r--drivers/rtc/rtc-ds1553.c12
-rw-r--r--drivers/rtc/rtc-ds1672.c114
-rw-r--r--drivers/rtc/rtc-ds3234.c290
-rw-r--r--drivers/rtc/rtc-m41t80.c43
-rw-r--r--drivers/rtc/rtc-m48t35.c1
-rw-r--r--drivers/rtc/rtc-max6900.c223
-rw-r--r--drivers/rtc/rtc-pcf8563.c58
-rw-r--r--drivers/rtc/rtc-pl030.c11
-rw-r--r--drivers/rtc/rtc-pl031.c14
-rw-r--r--drivers/rtc/rtc-rs5c372.c228
-rw-r--r--drivers/rtc/rtc-sh.c7
-rw-r--r--drivers/rtc/rtc-stk17ta8.c12
-rw-r--r--drivers/s390/net/ctcm_mpc.c2
-rw-r--r--drivers/serial/8250.c23
-rw-r--r--drivers/serial/s3c2400.c2
-rw-r--r--drivers/serial/s3c2410.c2
-rw-r--r--drivers/serial/s3c2412.c2
-rw-r--r--drivers/serial/s3c2440.c2
-rw-r--r--drivers/serial/samsung.c2
-rw-r--r--drivers/spi/mpc52xx_psc_spi.c55
-rw-r--r--drivers/spi/omap2_mcspi.c18
-rw-r--r--drivers/spi/omap_uwire.c23
-rw-r--r--drivers/spi/orion_spi.c5
-rw-r--r--drivers/spi/pxa2xx_spi.c54
-rw-r--r--drivers/spi/spi.c24
-rw-r--r--drivers/spi/spi_s3c24xx.c6
-rw-r--r--drivers/telephony/ixj.c2
-rw-r--r--drivers/usb/host/ohci-omap.c14
-rw-r--r--drivers/video/Kconfig109
-rw-r--r--drivers/video/Makefile3
-rw-r--r--drivers/video/atmel_lcdfb.c7
-rw-r--r--drivers/video/aty/radeon_accel.c313
-rw-r--r--drivers/video/aty/radeon_backlight.c2
-rw-r--r--drivers/video/aty/radeon_base.c35
-rw-r--r--drivers/video/aty/radeon_i2c.c4
-rw-r--r--drivers/video/aty/radeon_pm.c6
-rw-r--r--drivers/video/aty/radeonfb.h53
-rw-r--r--drivers/video/carminefb.c2
-rw-r--r--drivers/video/cirrusfb.c577
-rw-r--r--drivers/video/console/fbcon.c4
-rw-r--r--drivers/video/console/vgacon.c39
-rw-r--r--drivers/video/efifb.c191
-rw-r--r--drivers/video/fbmem.c17
-rw-r--r--drivers/video/fbmon.c8
-rw-r--r--drivers/video/imacfb.c376
-rw-r--r--drivers/video/intelfb/intelfb.h7
-rw-r--r--drivers/video/intelfb/intelfb_i2c.c1
-rw-r--r--drivers/video/intelfb/intelfbdrv.c7
-rw-r--r--drivers/video/intelfb/intelfbhw.c7
-rw-r--r--drivers/video/matrox/matroxfb_base.c9
-rw-r--r--drivers/video/neofb.c60
-rw-r--r--drivers/video/omap/dispc.c21
-rw-r--r--drivers/video/omap/dispc.h2
-rw-r--r--drivers/video/omap/lcd_h4.c4
-rw-r--r--drivers/video/omap/lcd_inn1610.c22
-rw-r--r--drivers/video/omap/lcd_osk.c10
-rw-r--r--drivers/video/omap/lcd_sx1.c99
-rw-r--r--drivers/video/omap/lcdc.c2
-rw-r--r--drivers/video/omap/lcdc.h2
-rw-r--r--drivers/video/omap/omapfb_main.c15
-rw-r--r--drivers/video/omap/rfbi.c9
-rw-r--r--drivers/video/omap/sossi.c8
-rw-r--r--drivers/video/s1d13xxxfb.c23
-rw-r--r--drivers/video/tdfxfb.c48
-rw-r--r--drivers/video/tmiofb.c1050
-rw-r--r--drivers/video/uvesafb.c11
-rw-r--r--drivers/video/vga16fb.c11
-rw-r--r--drivers/video/via/Makefile7
-rw-r--r--drivers/video/via/accel.c279
-rw-r--r--drivers/video/via/accel.h169
-rw-r--r--drivers/video/via/chip.h190
-rw-r--r--drivers/video/via/debug.h41
-rw-r--r--drivers/video/via/dvi.c682
-rw-r--r--drivers/video/via/dvi.h64
-rw-r--r--drivers/video/via/global.c60
-rw-r--r--drivers/video/via/global.h90
-rw-r--r--drivers/video/via/hw.c2865
-rw-r--r--drivers/video/via/hw.h933
-rw-r--r--drivers/video/via/iface.c78
-rw-r--r--drivers/video/via/iface.h38
-rw-r--r--drivers/video/via/ioctl.c112
-rw-r--r--drivers/video/via/ioctl.h210
-rw-r--r--drivers/video/via/lcd.c1821
-rw-r--r--drivers/video/via/lcd.h94
-rw-r--r--drivers/video/via/lcdtbl.h591
-rw-r--r--drivers/video/via/share.h1105
-rw-r--r--drivers/video/via/tbl1636.c71
-rw-r--r--drivers/video/via/tbl1636.h34
-rw-r--r--drivers/video/via/tblDPASetting.c109
-rw-r--r--drivers/video/via/tblDPASetting.h47
-rw-r--r--drivers/video/via/via_i2c.c177
-rw-r--r--drivers/video/via/via_i2c.h46
-rw-r--r--drivers/video/via/via_utility.c253
-rw-r--r--drivers/video/via/via_utility.h35
-rw-r--r--drivers/video/via/viafbdev.c2571
-rw-r--r--drivers/video/via/viafbdev.h112
-rw-r--r--drivers/video/via/viamode.c1086
-rw-r--r--drivers/video/via/viamode.h177
-rw-r--r--drivers/video/via/vt1636.c306
-rw-r--r--drivers/video/via/vt1636.h44
-rw-r--r--drivers/w1/masters/ds1wm.c10
-rw-r--r--drivers/w1/masters/ds2490.c348
-rw-r--r--drivers/w1/slaves/w1_ds2431.c312
-rw-r--r--drivers/w1/slaves/w1_therm.c72
-rw-r--r--drivers/w1/w1.c423
-rw-r--r--drivers/w1/w1.h34
-rw-r--r--drivers/w1/w1_family.c13
-rw-r--r--drivers/w1/w1_family.h3
-rw-r--r--drivers/w1/w1_int.c88
-rw-r--r--drivers/w1/w1_io.c85
255 files changed, 21902 insertions, 3252 deletions
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 6318f6b57360..d8e8c49c0cbd 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -54,7 +54,7 @@ config FIRMWARE_IN_KERNEL
54 such firmware, and do not wish to use an initrd. 54 such firmware, and do not wish to use an initrd.
55 55
56 This single option controls the inclusion of firmware for 56 This single option controls the inclusion of firmware for
57 every driver which usees request_firmare() and ships its 57 every driver which uses request_firmare() and ships its
58 firmware in the kernel source tree, to avoid a proliferation 58 firmware in the kernel source tree, to avoid a proliferation
59 of 'Include firmware for xxx device' options. 59 of 'Include firmware for xxx device' options.
60 60
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index c9c92b00fd55..b7e571031ecd 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -164,8 +164,7 @@ static ssize_t firmware_loading_store(struct device *dev,
164 } 164 }
165 /* fallthrough */ 165 /* fallthrough */
166 default: 166 default:
167 printk(KERN_ERR "%s: unexpected value (%d)\n", __func__, 167 dev_err(dev, "%s: unexpected value (%d)\n", __func__, loading);
168 loading);
169 /* fallthrough */ 168 /* fallthrough */
170 case -1: 169 case -1:
171 fw_load_abort(fw_priv); 170 fw_load_abort(fw_priv);
@@ -309,7 +308,7 @@ static int fw_register_device(struct device **dev_p, const char *fw_name,
309 *dev_p = NULL; 308 *dev_p = NULL;
310 309
311 if (!fw_priv || !f_dev) { 310 if (!fw_priv || !f_dev) {
312 printk(KERN_ERR "%s: kmalloc failed\n", __func__); 311 dev_err(device, "%s: kmalloc failed\n", __func__);
313 retval = -ENOMEM; 312 retval = -ENOMEM;
314 goto error_kfree; 313 goto error_kfree;
315 } 314 }
@@ -329,8 +328,7 @@ static int fw_register_device(struct device **dev_p, const char *fw_name,
329 f_dev->uevent_suppress = 1; 328 f_dev->uevent_suppress = 1;
330 retval = device_register(f_dev); 329 retval = device_register(f_dev);
331 if (retval) { 330 if (retval) {
332 printk(KERN_ERR "%s: device_register failed\n", 331 dev_err(device, "%s: device_register failed\n", __func__);
333 __func__);
334 goto error_kfree; 332 goto error_kfree;
335 } 333 }
336 *dev_p = f_dev; 334 *dev_p = f_dev;
@@ -363,15 +361,13 @@ static int fw_setup_device(struct firmware *fw, struct device **dev_p,
363 fw_priv->fw = fw; 361 fw_priv->fw = fw;
364 retval = sysfs_create_bin_file(&f_dev->kobj, &fw_priv->attr_data); 362 retval = sysfs_create_bin_file(&f_dev->kobj, &fw_priv->attr_data);
365 if (retval) { 363 if (retval) {
366 printk(KERN_ERR "%s: sysfs_create_bin_file failed\n", 364 dev_err(device, "%s: sysfs_create_bin_file failed\n", __func__);
367 __func__);
368 goto error_unreg; 365 goto error_unreg;
369 } 366 }
370 367
371 retval = device_create_file(f_dev, &dev_attr_loading); 368 retval = device_create_file(f_dev, &dev_attr_loading);
372 if (retval) { 369 if (retval) {
373 printk(KERN_ERR "%s: device_create_file failed\n", 370 dev_err(device, "%s: device_create_file failed\n", __func__);
374 __func__);
375 goto error_unreg; 371 goto error_unreg;
376 } 372 }
377 373
@@ -401,8 +397,8 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
401 397
402 *firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL); 398 *firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL);
403 if (!firmware) { 399 if (!firmware) {
404 printk(KERN_ERR "%s: kmalloc(struct firmware) failed\n", 400 dev_err(device, "%s: kmalloc(struct firmware) failed\n",
405 __func__); 401 __func__);
406 retval = -ENOMEM; 402 retval = -ENOMEM;
407 goto out; 403 goto out;
408 } 404 }
@@ -411,15 +407,15 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
411 builtin++) { 407 builtin++) {
412 if (strcmp(name, builtin->name)) 408 if (strcmp(name, builtin->name))
413 continue; 409 continue;
414 printk(KERN_INFO "firmware: using built-in firmware %s\n", 410 dev_info(device, "firmware: using built-in firmware %s\n",
415 name); 411 name);
416 firmware->size = builtin->size; 412 firmware->size = builtin->size;
417 firmware->data = builtin->data; 413 firmware->data = builtin->data;
418 return 0; 414 return 0;
419 } 415 }
420 416
421 if (uevent) 417 if (uevent)
422 printk(KERN_INFO "firmware: requesting %s\n", name); 418 dev_info(device, "firmware: requesting %s\n", name);
423 419
424 retval = fw_setup_device(firmware, &f_dev, name, device, uevent); 420 retval = fw_setup_device(firmware, &f_dev, name, device, uevent);
425 if (retval) 421 if (retval)
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 9e60f7c739c6..dfcbfe504867 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -42,10 +42,8 @@ struct resource *platform_get_resource(struct platform_device *dev,
42 for (i = 0; i < dev->num_resources; i++) { 42 for (i = 0; i < dev->num_resources; i++) {
43 struct resource *r = &dev->resource[i]; 43 struct resource *r = &dev->resource[i];
44 44
45 if ((r->flags & (IORESOURCE_IO|IORESOURCE_MEM| 45 if (type == resource_type(r) && num-- == 0)
46 IORESOURCE_IRQ|IORESOURCE_DMA)) == type) 46 return r;
47 if (num-- == 0)
48 return r;
49 } 47 }
50 return NULL; 48 return NULL;
51} 49}
@@ -78,10 +76,8 @@ struct resource *platform_get_resource_byname(struct platform_device *dev,
78 for (i = 0; i < dev->num_resources; i++) { 76 for (i = 0; i < dev->num_resources; i++) {
79 struct resource *r = &dev->resource[i]; 77 struct resource *r = &dev->resource[i];
80 78
81 if ((r->flags & (IORESOURCE_IO|IORESOURCE_MEM| 79 if (type == resource_type(r) && !strcmp(r->name, name))
82 IORESOURCE_IRQ|IORESOURCE_DMA)) == type) 80 return r;
83 if (!strcmp(r->name, name))
84 return r;
85 } 81 }
86 return NULL; 82 return NULL;
87} 83}
@@ -259,9 +255,9 @@ int platform_device_add(struct platform_device *pdev)
259 255
260 p = r->parent; 256 p = r->parent;
261 if (!p) { 257 if (!p) {
262 if (r->flags & IORESOURCE_MEM) 258 if (resource_type(r) == IORESOURCE_MEM)
263 p = &iomem_resource; 259 p = &iomem_resource;
264 else if (r->flags & IORESOURCE_IO) 260 else if (resource_type(r) == IORESOURCE_IO)
265 p = &ioport_resource; 261 p = &ioport_resource;
266 } 262 }
267 263
@@ -282,9 +278,14 @@ int platform_device_add(struct platform_device *pdev)
282 return ret; 278 return ret;
283 279
284 failed: 280 failed:
285 while (--i >= 0) 281 while (--i >= 0) {
286 if (pdev->resource[i].flags & (IORESOURCE_MEM|IORESOURCE_IO)) 282 struct resource *r = &pdev->resource[i];
287 release_resource(&pdev->resource[i]); 283 unsigned long type = resource_type(r);
284
285 if (type == IORESOURCE_MEM || type == IORESOURCE_IO)
286 release_resource(r);
287 }
288
288 return ret; 289 return ret;
289} 290}
290EXPORT_SYMBOL_GPL(platform_device_add); 291EXPORT_SYMBOL_GPL(platform_device_add);
@@ -306,7 +307,9 @@ void platform_device_del(struct platform_device *pdev)
306 307
307 for (i = 0; i < pdev->num_resources; i++) { 308 for (i = 0; i < pdev->num_resources; i++) {
308 struct resource *r = &pdev->resource[i]; 309 struct resource *r = &pdev->resource[i];
309 if (r->flags & (IORESOURCE_MEM|IORESOURCE_IO)) 310 unsigned long type = resource_type(r);
311
312 if (type == IORESOURCE_MEM || type == IORESOURCE_IO)
310 release_resource(r); 313 release_resource(r);
311 } 314 }
312 } 315 }
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index b0eb6afdd861..692c20ba5144 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -778,10 +778,7 @@ EXPORT_SYMBOL_GPL(device_suspend);
778 778
779void __suspend_report_result(const char *function, void *fn, int ret) 779void __suspend_report_result(const char *function, void *fn, int ret)
780{ 780{
781 if (ret) { 781 if (ret)
782 printk(KERN_ERR "%s(): ", function); 782 printk(KERN_ERR "%s(): %pF returns %d\n", function, fn, ret);
783 print_fn_descriptor_symbol("%s returns ", fn);
784 printk("%d\n", ret);
785 }
786} 783}
787EXPORT_SYMBOL_GPL(__suspend_report_result); 784EXPORT_SYMBOL_GPL(__suspend_report_result);
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 700ff9679457..122254155ae1 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -1043,15 +1043,6 @@ config HPET
1043 open selects one of the timers supported by the HPET. The timers are 1043 open selects one of the timers supported by the HPET. The timers are
1044 non-periodic and/or periodic. 1044 non-periodic and/or periodic.
1045 1045
1046config HPET_RTC_IRQ
1047 bool
1048 default HPET_EMULATE_RTC
1049 depends on RTC && HPET
1050 help
1051 If you say Y here, you will disable RTC_IRQ in drivers/char/rtc.c. It
1052 is assumed the platform called hpet_alloc with the RTC IRQ values for
1053 the HPET timers.
1054
1055config HPET_MMAP 1046config HPET_MMAP
1056 bool "Allow mmap of HPET" 1047 bool "Allow mmap of HPET"
1057 default y 1048 default y
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c
index b899d9182c7d..05674febb0c6 100644
--- a/drivers/char/applicom.c
+++ b/drivers/char/applicom.c
@@ -478,7 +478,7 @@ static int do_ac_read(int IndexCard, char __user *buf,
478 struct st_ram_io *st_loc, struct mailbox *mailbox) 478 struct st_ram_io *st_loc, struct mailbox *mailbox)
479{ 479{
480 void __iomem *from = apbs[IndexCard].RamIO + RAM_TO_PC; 480 void __iomem *from = apbs[IndexCard].RamIO + RAM_TO_PC;
481 unsigned char *to = (unsigned char *)&mailbox; 481 unsigned char *to = (unsigned char *)mailbox;
482#ifdef DEBUG 482#ifdef DEBUG
483 int c; 483 int c;
484#endif 484#endif
diff --git a/drivers/char/ds1286.c b/drivers/char/ds1286.c
index fb584938c9c3..5329d482b582 100644
--- a/drivers/char/ds1286.c
+++ b/drivers/char/ds1286.c
@@ -443,7 +443,6 @@ static void ds1286_get_time(struct rtc_time *rtc_tm)
443{ 443{
444 unsigned char save_control; 444 unsigned char save_control;
445 unsigned long flags; 445 unsigned long flags;
446 unsigned long uip_watchdog = jiffies;
447 446
448 /* 447 /*
449 * read RTC once any update in progress is done. The update 448 * read RTC once any update in progress is done. The update
@@ -456,8 +455,7 @@ static void ds1286_get_time(struct rtc_time *rtc_tm)
456 */ 455 */
457 456
458 if (ds1286_is_updating() != 0) 457 if (ds1286_is_updating() != 0)
459 while (time_before(jiffies, uip_watchdog + 2*HZ/100)) 458 msleep(20);
460 barrier();
461 459
462 /* 460 /*
463 * Only the values that we read from the RTC are set. We leave 461 * Only the values that we read from the RTC are set. We leave
diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c
index 51738bdd834e..d4e7dca06e4f 100644
--- a/drivers/char/hw_random/omap-rng.c
+++ b/drivers/char/hw_random/omap-rng.c
@@ -118,18 +118,21 @@ static int __init omap_rng_probe(struct platform_device *pdev)
118 118
119 mem = request_mem_region(res->start, res->end - res->start + 1, 119 mem = request_mem_region(res->start, res->end - res->start + 1,
120 pdev->name); 120 pdev->name);
121 if (mem == NULL) 121 if (mem == NULL) {
122 return -EBUSY; 122 ret = -EBUSY;
123 goto err_region;
124 }
123 125
124 dev_set_drvdata(&pdev->dev, mem); 126 dev_set_drvdata(&pdev->dev, mem);
125 rng_base = (u32 __force __iomem *)io_p2v(res->start); 127 rng_base = ioremap(res->start, res->end - res->start + 1);
128 if (!rng_base) {
129 ret = -ENOMEM;
130 goto err_ioremap;
131 }
126 132
127 ret = hwrng_register(&omap_rng_ops); 133 ret = hwrng_register(&omap_rng_ops);
128 if (ret) { 134 if (ret)
129 release_resource(mem); 135 goto err_register;
130 rng_base = NULL;
131 return ret;
132 }
133 136
134 dev_info(&pdev->dev, "OMAP Random Number Generator ver. %02x\n", 137 dev_info(&pdev->dev, "OMAP Random Number Generator ver. %02x\n",
135 omap_rng_read_reg(RNG_REV_REG)); 138 omap_rng_read_reg(RNG_REV_REG));
@@ -138,6 +141,18 @@ static int __init omap_rng_probe(struct platform_device *pdev)
138 rng_dev = pdev; 141 rng_dev = pdev;
139 142
140 return 0; 143 return 0;
144
145err_register:
146 iounmap(rng_base);
147 rng_base = NULL;
148err_ioremap:
149 release_resource(mem);
150err_region:
151 if (cpu_is_omap24xx()) {
152 clk_disable(rng_ick);
153 clk_put(rng_ick);
154 }
155 return ret;
141} 156}
142 157
143static int __exit omap_rng_remove(struct platform_device *pdev) 158static int __exit omap_rng_remove(struct platform_device *pdev)
@@ -148,6 +163,8 @@ static int __exit omap_rng_remove(struct platform_device *pdev)
148 163
149 omap_rng_write_reg(RNG_MASK_REG, 0x0); 164 omap_rng_write_reg(RNG_MASK_REG, 0x0);
150 165
166 iounmap(rng_base);
167
151 if (cpu_is_omap24xx()) { 168 if (cpu_is_omap24xx()) {
152 clk_disable(rng_ick); 169 clk_disable(rng_ick);
153 clk_put(rng_ick); 170 clk_put(rng_ick);
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 7b3a212c86b1..de26a978fbdd 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -1249,7 +1249,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
1249 return; 1249 return;
1250 } 1250 }
1251 1251
1252 if (keycode > NR_KEYS) 1252 if (keycode >= NR_KEYS)
1253 if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8) 1253 if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8)
1254 keysym = K(KT_BRL, keycode - KEY_BRL_DOT1 + 1); 1254 keysym = K(KT_BRL, keycode - KEY_BRL_DOT1 + 1);
1255 else 1255 else
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index 5df4003ad873..12d327a2c9ba 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -513,7 +513,7 @@ static int moxa_real_load_code(struct moxa_board_conf *brd, const void *ptr,
513 size_t len) 513 size_t len)
514{ 514{
515 void __iomem *baseAddr = brd->basemem; 515 void __iomem *baseAddr = brd->basemem;
516 const u16 *uptr = ptr; 516 const __le16 *uptr = ptr;
517 size_t wlen, len2, j; 517 size_t wlen, len2, j;
518 unsigned long key, loadbuf, loadlen, checksum, checksum_ok; 518 unsigned long key, loadbuf, loadlen, checksum, checksum_ok;
519 unsigned int i, retry; 519 unsigned int i, retry;
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 6af435b89867..c8752eaad483 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1205,7 +1205,7 @@ static int proc_do_uuid(ctl_table *table, int write, struct file *filp,
1205 return proc_dostring(&fake_table, write, filp, buffer, lenp, ppos); 1205 return proc_dostring(&fake_table, write, filp, buffer, lenp, ppos);
1206} 1206}
1207 1207
1208static int uuid_strategy(ctl_table *table, int __user *name, int nlen, 1208static int uuid_strategy(ctl_table *table,
1209 void __user *oldval, size_t __user *oldlenp, 1209 void __user *oldval, size_t __user *oldlenp,
1210 void __user *newval, size_t newlen) 1210 void __user *newval, size_t newlen)
1211{ 1211{
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index b47710c17885..17683de95717 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -96,7 +96,7 @@ static unsigned long rtc_port;
96static int rtc_irq; 96static int rtc_irq;
97#endif 97#endif
98 98
99#ifdef CONFIG_HPET_RTC_IRQ 99#ifdef CONFIG_HPET_EMULATE_RTC
100#undef RTC_IRQ 100#undef RTC_IRQ
101#endif 101#endif
102 102
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index 8fdfe9c871e3..dce4cc0e6953 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -23,6 +23,7 @@
23#include <linux/reboot.h> 23#include <linux/reboot.h>
24#include <linux/sysrq.h> 24#include <linux/sysrq.h>
25#include <linux/kbd_kern.h> 25#include <linux/kbd_kern.h>
26#include <linux/proc_fs.h>
26#include <linux/quotaops.h> 27#include <linux/quotaops.h>
27#include <linux/kernel.h> 28#include <linux/kernel.h>
28#include <linux/module.h> 29#include <linux/module.h>
@@ -326,6 +327,7 @@ static struct sysrq_key_op sysrq_moom_op = {
326 .handler = sysrq_handle_moom, 327 .handler = sysrq_handle_moom,
327 .help_msg = "Full", 328 .help_msg = "Full",
328 .action_msg = "Manual OOM execution", 329 .action_msg = "Manual OOM execution",
330 .enable_mask = SYSRQ_ENABLE_SIGNAL,
329}; 331};
330 332
331static void sysrq_handle_kill(int key, struct tty_struct *tty) 333static void sysrq_handle_kill(int key, struct tty_struct *tty)
@@ -533,3 +535,32 @@ int unregister_sysrq_key(int key, struct sysrq_key_op *op_p)
533 return __sysrq_swap_key_ops(key, NULL, op_p); 535 return __sysrq_swap_key_ops(key, NULL, op_p);
534} 536}
535EXPORT_SYMBOL(unregister_sysrq_key); 537EXPORT_SYMBOL(unregister_sysrq_key);
538
539#ifdef CONFIG_PROC_FS
540/*
541 * writing 'C' to /proc/sysrq-trigger is like sysrq-C
542 */
543static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf,
544 size_t count, loff_t *ppos)
545{
546 if (count) {
547 char c;
548
549 if (get_user(c, buf))
550 return -EFAULT;
551 __handle_sysrq(c, NULL, 0);
552 }
553 return count;
554}
555
556static const struct file_operations proc_sysrq_trigger_operations = {
557 .write = write_sysrq_trigger,
558};
559
560static int __init sysrq_init(void)
561{
562 proc_create("sysrq-trigger", S_IWUSR, NULL, &proc_sysrq_trigger_operations);
563 return 0;
564}
565module_init(sysrq_init);
566#endif
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 1fee7034a386..e70d13defde4 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -525,19 +525,19 @@ void tpm_get_timeouts(struct tpm_chip *chip)
525 timeout = 525 timeout =
526 be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX))); 526 be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX)));
527 if (timeout) 527 if (timeout)
528 chip->vendor.timeout_a = msecs_to_jiffies(timeout); 528 chip->vendor.timeout_a = usecs_to_jiffies(timeout);
529 timeout = 529 timeout =
530 be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_2_IDX))); 530 be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_2_IDX)));
531 if (timeout) 531 if (timeout)
532 chip->vendor.timeout_b = msecs_to_jiffies(timeout); 532 chip->vendor.timeout_b = usecs_to_jiffies(timeout);
533 timeout = 533 timeout =
534 be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_3_IDX))); 534 be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_3_IDX)));
535 if (timeout) 535 if (timeout)
536 chip->vendor.timeout_c = msecs_to_jiffies(timeout); 536 chip->vendor.timeout_c = usecs_to_jiffies(timeout);
537 timeout = 537 timeout =
538 be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_4_IDX))); 538 be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_4_IDX)));
539 if (timeout) 539 if (timeout)
540 chip->vendor.timeout_d = msecs_to_jiffies(timeout); 540 chip->vendor.timeout_d = usecs_to_jiffies(timeout);
541 541
542duration: 542duration:
543 memcpy(data, tpm_cap, sizeof(tpm_cap)); 543 memcpy(data, tpm_cap, sizeof(tpm_cap));
@@ -554,15 +554,22 @@ duration:
554 return; 554 return;
555 555
556 chip->vendor.duration[TPM_SHORT] = 556 chip->vendor.duration[TPM_SHORT] =
557 msecs_to_jiffies(be32_to_cpu 557 usecs_to_jiffies(be32_to_cpu
558 (*((__be32 *) (data + 558 (*((__be32 *) (data +
559 TPM_GET_CAP_RET_UINT32_1_IDX)))); 559 TPM_GET_CAP_RET_UINT32_1_IDX))));
560 /* The Broadcom BCM0102 chipset in a Dell Latitude D820 gets the above
561 * value wrong and apparently reports msecs rather than usecs. So we
562 * fix up the resulting too-small TPM_SHORT value to make things work.
563 */
564 if (chip->vendor.duration[TPM_SHORT] < (HZ/100))
565 chip->vendor.duration[TPM_SHORT] = HZ;
566
560 chip->vendor.duration[TPM_MEDIUM] = 567 chip->vendor.duration[TPM_MEDIUM] =
561 msecs_to_jiffies(be32_to_cpu 568 usecs_to_jiffies(be32_to_cpu
562 (*((__be32 *) (data + 569 (*((__be32 *) (data +
563 TPM_GET_CAP_RET_UINT32_2_IDX)))); 570 TPM_GET_CAP_RET_UINT32_2_IDX))));
564 chip->vendor.duration[TPM_LONG] = 571 chip->vendor.duration[TPM_LONG] =
565 msecs_to_jiffies(be32_to_cpu 572 usecs_to_jiffies(be32_to_cpu
566 (*((__be32 *) (data + 573 (*((__be32 *) (data +
567 TPM_GET_CAP_RET_UINT32_3_IDX)))); 574 TPM_GET_CAP_RET_UINT32_3_IDX))));
568} 575}
@@ -1180,11 +1187,8 @@ struct tpm_chip *tpm_register_hardware(struct device *dev,
1180 chip = kzalloc(sizeof(*chip), GFP_KERNEL); 1187 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
1181 devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL); 1188 devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL);
1182 1189
1183 if (chip == NULL || devname == NULL) { 1190 if (chip == NULL || devname == NULL)
1184 kfree(chip); 1191 goto out_free;
1185 kfree(devname);
1186 return NULL;
1187 }
1188 1192
1189 mutex_init(&chip->buffer_mutex); 1193 mutex_init(&chip->buffer_mutex);
1190 mutex_init(&chip->tpm_mutex); 1194 mutex_init(&chip->tpm_mutex);
@@ -1201,8 +1205,7 @@ struct tpm_chip *tpm_register_hardware(struct device *dev,
1201 1205
1202 if (chip->dev_num >= TPM_NUM_DEVICES) { 1206 if (chip->dev_num >= TPM_NUM_DEVICES) {
1203 dev_err(dev, "No available tpm device numbers\n"); 1207 dev_err(dev, "No available tpm device numbers\n");
1204 kfree(chip); 1208 goto out_free;
1205 return NULL;
1206 } else if (chip->dev_num == 0) 1209 } else if (chip->dev_num == 0)
1207 chip->vendor.miscdev.minor = TPM_MINOR; 1210 chip->vendor.miscdev.minor = TPM_MINOR;
1208 else 1211 else
@@ -1243,6 +1246,11 @@ struct tpm_chip *tpm_register_hardware(struct device *dev,
1243 spin_unlock(&driver_lock); 1246 spin_unlock(&driver_lock);
1244 1247
1245 return chip; 1248 return chip;
1249
1250out_free:
1251 kfree(chip);
1252 kfree(devname);
1253 return NULL;
1246} 1254}
1247EXPORT_SYMBOL_GPL(tpm_register_hardware); 1255EXPORT_SYMBOL_GPL(tpm_register_hardware);
1248 1256
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index a0f7ffb68087..d8f83e26e4a4 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -59,7 +59,7 @@
59 * by Martin Mares <mj@atrey.karlin.mff.cuni.cz>, July 1998 59 * by Martin Mares <mj@atrey.karlin.mff.cuni.cz>, July 1998
60 * 60 *
61 * Removed old-style timers, introduced console_timer, made timer 61 * Removed old-style timers, introduced console_timer, made timer
62 * deletion SMP-safe. 17Jun00, Andrew Morton <andrewm@uow.edu.au> 62 * deletion SMP-safe. 17Jun00, Andrew Morton
63 * 63 *
64 * Removed console_lock, enabled interrupts across all console operations 64 * Removed console_lock, enabled interrupts across all console operations
65 * 13 March 2001, Andrew Morton 65 * 13 March 2001, Andrew Morton
diff --git a/drivers/edac/i5000_edac.c b/drivers/edac/i5000_edac.c
index 4a16b5b61cfb..f0d9b415db50 100644
--- a/drivers/edac/i5000_edac.c
+++ b/drivers/edac/i5000_edac.c
@@ -119,6 +119,7 @@
119#define FERR_NF_UNCORRECTABLE (FERR_NF_M12ERR | \ 119#define FERR_NF_UNCORRECTABLE (FERR_NF_M12ERR | \
120 FERR_NF_M11ERR | \ 120 FERR_NF_M11ERR | \
121 FERR_NF_M10ERR | \ 121 FERR_NF_M10ERR | \
122 FERR_NF_M9ERR | \
122 FERR_NF_M8ERR | \ 123 FERR_NF_M8ERR | \
123 FERR_NF_M7ERR | \ 124 FERR_NF_M7ERR | \
124 FERR_NF_M6ERR | \ 125 FERR_NF_M6ERR | \
@@ -301,6 +302,9 @@ static char *numcol_toString[] = {
301}; 302};
302#endif 303#endif
303 304
305/* enables the report of miscellaneous messages as CE errors - default off */
306static int misc_messages;
307
304/* Enumeration of supported devices */ 308/* Enumeration of supported devices */
305enum i5000_chips { 309enum i5000_chips {
306 I5000P = 0, 310 I5000P = 0,
@@ -466,7 +470,8 @@ static void i5000_process_fatal_error_info(struct mem_ctl_info *mci,
466 struct i5000_error_info *info, 470 struct i5000_error_info *info,
467 int handle_errors) 471 int handle_errors)
468{ 472{
469 char msg[EDAC_MC_LABEL_LEN + 1 + 90]; 473 char msg[EDAC_MC_LABEL_LEN + 1 + 160];
474 char *specific = NULL;
470 u32 allErrors; 475 u32 allErrors;
471 int branch; 476 int branch;
472 int channel; 477 int channel;
@@ -480,11 +485,6 @@ static void i5000_process_fatal_error_info(struct mem_ctl_info *mci,
480 if (!allErrors) 485 if (!allErrors)
481 return; /* if no error, return now */ 486 return; /* if no error, return now */
482 487
483 /* ONLY ONE of the possible error bits will be set, as per the docs */
484 i5000_mc_printk(mci, KERN_ERR,
485 "FATAL ERRORS Found!!! 1st FATAL Err Reg= 0x%x\n",
486 allErrors);
487
488 branch = EXTRACT_FBDCHAN_INDX(info->ferr_fat_fbd); 488 branch = EXTRACT_FBDCHAN_INDX(info->ferr_fat_fbd);
489 channel = branch; 489 channel = branch;
490 490
@@ -501,28 +501,42 @@ static void i5000_process_fatal_error_info(struct mem_ctl_info *mci,
501 rdwr ? "Write" : "Read", ras, cas); 501 rdwr ? "Write" : "Read", ras, cas);
502 502
503 /* Only 1 bit will be on */ 503 /* Only 1 bit will be on */
504 if (allErrors & FERR_FAT_M1ERR) { 504 switch (allErrors) {
505 i5000_mc_printk(mci, KERN_ERR, 505 case FERR_FAT_M1ERR:
506 "Alert on non-redundant retry or fast " 506 specific = "Alert on non-redundant retry or fast "
507 "reset timeout\n"); 507 "reset timeout";
508 508 break;
509 } else if (allErrors & FERR_FAT_M2ERR) { 509 case FERR_FAT_M2ERR:
510 i5000_mc_printk(mci, KERN_ERR, 510 specific = "Northbound CRC error on non-redundant "
511 "Northbound CRC error on non-redundant " 511 "retry";
512 "retry\n"); 512 break;
513 513 case FERR_FAT_M3ERR:
514 } else if (allErrors & FERR_FAT_M3ERR) { 514 {
515 i5000_mc_printk(mci, KERN_ERR, 515 static int done;
516 ">Tmid Thermal event with intelligent " 516
517 "throttling disabled\n"); 517 /*
518 * This error is generated to inform that the intelligent
519 * throttling is disabled and the temperature passed the
520 * specified middle point. Since this is something the BIOS
521 * should take care of, we'll warn only once to avoid
522 * worthlessly flooding the log.
523 */
524 if (done)
525 return;
526 done++;
527
528 specific = ">Tmid Thermal event with intelligent "
529 "throttling disabled";
530 }
531 break;
518 } 532 }
519 533
520 /* Form out message */ 534 /* Form out message */
521 snprintf(msg, sizeof(msg), 535 snprintf(msg, sizeof(msg),
522 "(Branch=%d DRAM-Bank=%d RDWR=%s RAS=%d CAS=%d " 536 "(Branch=%d DRAM-Bank=%d RDWR=%s RAS=%d CAS=%d "
523 "FATAL Err=0x%x)", 537 "FATAL Err=0x%x (%s))",
524 branch >> 1, bank, rdwr ? "Write" : "Read", ras, cas, 538 branch >> 1, bank, rdwr ? "Write" : "Read", ras, cas,
525 allErrors); 539 allErrors, specific);
526 540
527 /* Call the helper to output message */ 541 /* Call the helper to output message */
528 edac_mc_handle_fbd_ue(mci, rank, channel, channel + 1, msg); 542 edac_mc_handle_fbd_ue(mci, rank, channel, channel + 1, msg);
@@ -539,7 +553,8 @@ static void i5000_process_nonfatal_error_info(struct mem_ctl_info *mci,
539 struct i5000_error_info *info, 553 struct i5000_error_info *info,
540 int handle_errors) 554 int handle_errors)
541{ 555{
542 char msg[EDAC_MC_LABEL_LEN + 1 + 90]; 556 char msg[EDAC_MC_LABEL_LEN + 1 + 170];
557 char *specific = NULL;
543 u32 allErrors; 558 u32 allErrors;
544 u32 ue_errors; 559 u32 ue_errors;
545 u32 ce_errors; 560 u32 ce_errors;
@@ -557,10 +572,6 @@ static void i5000_process_nonfatal_error_info(struct mem_ctl_info *mci,
557 return; /* if no error, return now */ 572 return; /* if no error, return now */
558 573
559 /* ONLY ONE of the possible error bits will be set, as per the docs */ 574 /* ONLY ONE of the possible error bits will be set, as per the docs */
560 i5000_mc_printk(mci, KERN_WARNING,
561 "NON-FATAL ERRORS Found!!! 1st NON-FATAL Err "
562 "Reg= 0x%x\n", allErrors);
563
564 ue_errors = allErrors & FERR_NF_UNCORRECTABLE; 575 ue_errors = allErrors & FERR_NF_UNCORRECTABLE;
565 if (ue_errors) { 576 if (ue_errors) {
566 debugf0("\tUncorrected bits= 0x%x\n", ue_errors); 577 debugf0("\tUncorrected bits= 0x%x\n", ue_errors);
@@ -579,12 +590,47 @@ static void i5000_process_nonfatal_error_info(struct mem_ctl_info *mci,
579 rank, channel, channel + 1, branch >> 1, bank, 590 rank, channel, channel + 1, branch >> 1, bank,
580 rdwr ? "Write" : "Read", ras, cas); 591 rdwr ? "Write" : "Read", ras, cas);
581 592
593 switch (ue_errors) {
594 case FERR_NF_M12ERR:
595 specific = "Non-Aliased Uncorrectable Patrol Data ECC";
596 break;
597 case FERR_NF_M11ERR:
598 specific = "Non-Aliased Uncorrectable Spare-Copy "
599 "Data ECC";
600 break;
601 case FERR_NF_M10ERR:
602 specific = "Non-Aliased Uncorrectable Mirrored Demand "
603 "Data ECC";
604 break;
605 case FERR_NF_M9ERR:
606 specific = "Non-Aliased Uncorrectable Non-Mirrored "
607 "Demand Data ECC";
608 break;
609 case FERR_NF_M8ERR:
610 specific = "Aliased Uncorrectable Patrol Data ECC";
611 break;
612 case FERR_NF_M7ERR:
613 specific = "Aliased Uncorrectable Spare-Copy Data ECC";
614 break;
615 case FERR_NF_M6ERR:
616 specific = "Aliased Uncorrectable Mirrored Demand "
617 "Data ECC";
618 break;
619 case FERR_NF_M5ERR:
620 specific = "Aliased Uncorrectable Non-Mirrored Demand "
621 "Data ECC";
622 break;
623 case FERR_NF_M4ERR:
624 specific = "Uncorrectable Data ECC on Replay";
625 break;
626 }
627
582 /* Form out message */ 628 /* Form out message */
583 snprintf(msg, sizeof(msg), 629 snprintf(msg, sizeof(msg),
584 "(Branch=%d DRAM-Bank=%d RDWR=%s RAS=%d " 630 "(Branch=%d DRAM-Bank=%d RDWR=%s RAS=%d "
585 "CAS=%d, UE Err=0x%x)", 631 "CAS=%d, UE Err=0x%x (%s))",
586 branch >> 1, bank, rdwr ? "Write" : "Read", ras, cas, 632 branch >> 1, bank, rdwr ? "Write" : "Read", ras, cas,
587 ue_errors); 633 ue_errors, specific);
588 634
589 /* Call the helper to output message */ 635 /* Call the helper to output message */
590 edac_mc_handle_fbd_ue(mci, rank, channel, channel + 1, msg); 636 edac_mc_handle_fbd_ue(mci, rank, channel, channel + 1, msg);
@@ -616,51 +662,74 @@ static void i5000_process_nonfatal_error_info(struct mem_ctl_info *mci,
616 rank, channel, branch >> 1, bank, 662 rank, channel, branch >> 1, bank,
617 rdwr ? "Write" : "Read", ras, cas); 663 rdwr ? "Write" : "Read", ras, cas);
618 664
665 switch (ce_errors) {
666 case FERR_NF_M17ERR:
667 specific = "Correctable Non-Mirrored Demand Data ECC";
668 break;
669 case FERR_NF_M18ERR:
670 specific = "Correctable Mirrored Demand Data ECC";
671 break;
672 case FERR_NF_M19ERR:
673 specific = "Correctable Spare-Copy Data ECC";
674 break;
675 case FERR_NF_M20ERR:
676 specific = "Correctable Patrol Data ECC";
677 break;
678 }
679
619 /* Form out message */ 680 /* Form out message */
620 snprintf(msg, sizeof(msg), 681 snprintf(msg, sizeof(msg),
621 "(Branch=%d DRAM-Bank=%d RDWR=%s RAS=%d " 682 "(Branch=%d DRAM-Bank=%d RDWR=%s RAS=%d "
622 "CAS=%d, CE Err=0x%x)", branch >> 1, bank, 683 "CAS=%d, CE Err=0x%x (%s))", branch >> 1, bank,
623 rdwr ? "Write" : "Read", ras, cas, ce_errors); 684 rdwr ? "Write" : "Read", ras, cas, ce_errors,
685 specific);
624 686
625 /* Call the helper to output message */ 687 /* Call the helper to output message */
626 edac_mc_handle_fbd_ce(mci, rank, channel, msg); 688 edac_mc_handle_fbd_ce(mci, rank, channel, msg);
627 } 689 }
628 690
629 /* See if any of the thermal errors have fired */ 691 if (!misc_messages)
630 misc_errors = allErrors & FERR_NF_THERMAL; 692 return;
631 if (misc_errors) {
632 i5000_printk(KERN_WARNING, "\tTHERMAL Error, bits= 0x%x\n",
633 misc_errors);
634 }
635
636 /* See if any of the thermal errors have fired */
637 misc_errors = allErrors & FERR_NF_NON_RETRY;
638 if (misc_errors) {
639 i5000_printk(KERN_WARNING, "\tNON-Retry Errors, bits= 0x%x\n",
640 misc_errors);
641 }
642 693
643 /* See if any of the thermal errors have fired */ 694 misc_errors = allErrors & (FERR_NF_NON_RETRY | FERR_NF_NORTH_CRC |
644 misc_errors = allErrors & FERR_NF_NORTH_CRC; 695 FERR_NF_SPD_PROTOCOL | FERR_NF_DIMM_SPARE);
645 if (misc_errors) { 696 if (misc_errors) {
646 i5000_printk(KERN_WARNING, 697 switch (misc_errors) {
647 "\tNORTHBOUND CRC Error, bits= 0x%x\n", 698 case FERR_NF_M13ERR:
648 misc_errors); 699 specific = "Non-Retry or Redundant Retry FBD Memory "
649 } 700 "Alert or Redundant Fast Reset Timeout";
701 break;
702 case FERR_NF_M14ERR:
703 specific = "Non-Retry or Redundant Retry FBD "
704 "Configuration Alert";
705 break;
706 case FERR_NF_M15ERR:
707 specific = "Non-Retry or Redundant Retry FBD "
708 "Northbound CRC error on read data";
709 break;
710 case FERR_NF_M21ERR:
711 specific = "FBD Northbound CRC error on "
712 "FBD Sync Status";
713 break;
714 case FERR_NF_M22ERR:
715 specific = "SPD protocol error";
716 break;
717 case FERR_NF_M27ERR:
718 specific = "DIMM-spare copy started";
719 break;
720 case FERR_NF_M28ERR:
721 specific = "DIMM-spare copy completed";
722 break;
723 }
724 branch = EXTRACT_FBDCHAN_INDX(info->ferr_nf_fbd);
650 725
651 /* See if any of the thermal errors have fired */ 726 /* Form out message */
652 misc_errors = allErrors & FERR_NF_SPD_PROTOCOL; 727 snprintf(msg, sizeof(msg),
653 if (misc_errors) { 728 "(Branch=%d Err=%#x (%s))", branch >> 1,
654 i5000_printk(KERN_WARNING, 729 misc_errors, specific);
655 "\tSPD Protocol Error, bits= 0x%x\n",
656 misc_errors);
657 }
658 730
659 /* See if any of the thermal errors have fired */ 731 /* Call the helper to output message */
660 misc_errors = allErrors & FERR_NF_DIMM_SPARE; 732 edac_mc_handle_fbd_ce(mci, 0, 0, msg);
661 if (misc_errors) {
662 i5000_printk(KERN_WARNING, "\tDIMM-Spare Error, bits= 0x%x\n",
663 misc_errors);
664 } 733 }
665} 734}
666 735
@@ -1497,3 +1566,6 @@ MODULE_DESCRIPTION("MC Driver for Intel I5000 memory controllers - "
1497 1566
1498module_param(edac_op_state, int, 0444); 1567module_param(edac_op_state, int, 0444);
1499MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting state: 0=Poll,1=NMI"); 1568MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting state: 0=Poll,1=NMI");
1569module_param(misc_messages, int, 0444);
1570MODULE_PARM_DESC(misc_messages, "Log miscellaneous non fatal messages");
1571
diff --git a/drivers/edac/i82443bxgx_edac.c b/drivers/edac/i82443bxgx_edac.c
index c5305e3ee434..577760a82a0f 100644
--- a/drivers/edac/i82443bxgx_edac.c
+++ b/drivers/edac/i82443bxgx_edac.c
@@ -114,6 +114,12 @@ struct i82443bxgx_edacmc_error_info {
114 114
115static struct edac_pci_ctl_info *i82443bxgx_pci; 115static struct edac_pci_ctl_info *i82443bxgx_pci;
116 116
117static struct pci_dev *mci_pdev; /* init dev: in case that AGP code has
118 * already registered driver
119 */
120
121static int i82443bxgx_registered = 1;
122
117static void i82443bxgx_edacmc_get_error_info(struct mem_ctl_info *mci, 123static void i82443bxgx_edacmc_get_error_info(struct mem_ctl_info *mci,
118 struct i82443bxgx_edacmc_error_info 124 struct i82443bxgx_edacmc_error_info
119 *info) 125 *info)
@@ -345,10 +351,17 @@ EXPORT_SYMBOL_GPL(i82443bxgx_edacmc_probe1);
345static int __devinit i82443bxgx_edacmc_init_one(struct pci_dev *pdev, 351static int __devinit i82443bxgx_edacmc_init_one(struct pci_dev *pdev,
346 const struct pci_device_id *ent) 352 const struct pci_device_id *ent)
347{ 353{
354 int rc;
355
348 debugf0("MC: " __FILE__ ": %s()\n", __func__); 356 debugf0("MC: " __FILE__ ": %s()\n", __func__);
349 357
350 /* don't need to call pci_device_enable() */ 358 /* don't need to call pci_device_enable() */
351 return i82443bxgx_edacmc_probe1(pdev, ent->driver_data); 359 rc = i82443bxgx_edacmc_probe1(pdev, ent->driver_data);
360
361 if (mci_pdev == NULL)
362 mci_pdev = pci_dev_get(pdev);
363
364 return rc;
352} 365}
353 366
354static void __devexit i82443bxgx_edacmc_remove_one(struct pci_dev *pdev) 367static void __devexit i82443bxgx_edacmc_remove_one(struct pci_dev *pdev)
@@ -387,15 +400,61 @@ static struct pci_driver i82443bxgx_edacmc_driver = {
387 400
388static int __init i82443bxgx_edacmc_init(void) 401static int __init i82443bxgx_edacmc_init(void)
389{ 402{
403 int pci_rc;
390 /* Ensure that the OPSTATE is set correctly for POLL or NMI */ 404 /* Ensure that the OPSTATE is set correctly for POLL or NMI */
391 opstate_init(); 405 opstate_init();
392 406
393 return pci_register_driver(&i82443bxgx_edacmc_driver); 407 pci_rc = pci_register_driver(&i82443bxgx_edacmc_driver);
408 if (pci_rc < 0)
409 goto fail0;
410
411 if (mci_pdev == NULL) {
412 const struct pci_device_id *id = &i82443bxgx_pci_tbl[0];
413 int i = 0;
414 i82443bxgx_registered = 0;
415
416 while (mci_pdev == NULL && id->vendor != 0) {
417 mci_pdev = pci_get_device(id->vendor,
418 id->device, NULL);
419 i++;
420 id = &i82443bxgx_pci_tbl[i];
421 }
422 if (!mci_pdev) {
423 debugf0("i82443bxgx pci_get_device fail\n");
424 pci_rc = -ENODEV;
425 goto fail1;
426 }
427
428 pci_rc = i82443bxgx_edacmc_init_one(mci_pdev, i82443bxgx_pci_tbl);
429
430 if (pci_rc < 0) {
431 debugf0("i82443bxgx init fail\n");
432 pci_rc = -ENODEV;
433 goto fail1;
434 }
435 }
436
437 return 0;
438
439fail1:
440 pci_unregister_driver(&i82443bxgx_edacmc_driver);
441
442fail0:
443 if (mci_pdev != NULL)
444 pci_dev_put(mci_pdev);
445
446 return pci_rc;
394} 447}
395 448
396static void __exit i82443bxgx_edacmc_exit(void) 449static void __exit i82443bxgx_edacmc_exit(void)
397{ 450{
398 pci_unregister_driver(&i82443bxgx_edacmc_driver); 451 pci_unregister_driver(&i82443bxgx_edacmc_driver);
452
453 if (!i82443bxgx_registered)
454 i82443bxgx_edacmc_remove_one(mci_pdev);
455
456 if (mci_pdev)
457 pci_dev_put(mci_pdev);
399} 458}
400 459
401module_init(i82443bxgx_edacmc_init); 460module_init(i82443bxgx_edacmc_init);
diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c
index 2265d9ca1535..0cfcb2d075a0 100644
--- a/drivers/edac/mpc85xx_edac.c
+++ b/drivers/edac/mpc85xx_edac.c
@@ -17,6 +17,7 @@
17#include <linux/io.h> 17#include <linux/io.h>
18#include <linux/mod_devicetable.h> 18#include <linux/mod_devicetable.h>
19#include <linux/edac.h> 19#include <linux/edac.h>
20#include <linux/smp.h>
20 21
21#include <linux/of_platform.h> 22#include <linux/of_platform.h>
22#include <linux/of_device.h> 23#include <linux/of_device.h>
@@ -40,7 +41,7 @@ static u32 orig_pci_err_en;
40#endif 41#endif
41 42
42static u32 orig_l2_err_disable; 43static u32 orig_l2_err_disable;
43static u32 orig_hid1; 44static u32 orig_hid1[2];
44 45
45/************************ MC SYSFS parts ***********************************/ 46/************************ MC SYSFS parts ***********************************/
46 47
@@ -647,6 +648,9 @@ static struct of_device_id mpc85xx_l2_err_of_match[] = {
647 { 648 {
648 .compatible = "fsl,8568-l2-cache-controller", 649 .compatible = "fsl,8568-l2-cache-controller",
649 }, 650 },
651 {
652 .compatible = "fsl,mpc8572-l2-cache-controller",
653 },
650 {}, 654 {},
651}; 655};
652 656
@@ -912,7 +916,8 @@ static int __devinit mpc85xx_mc_err_probe(struct of_device *op,
912 /* register interrupts */ 916 /* register interrupts */
913 pdata->irq = irq_of_parse_and_map(op->node, 0); 917 pdata->irq = irq_of_parse_and_map(op->node, 0);
914 res = devm_request_irq(&op->dev, pdata->irq, 918 res = devm_request_irq(&op->dev, pdata->irq,
915 mpc85xx_mc_isr, IRQF_DISABLED, 919 mpc85xx_mc_isr,
920 IRQF_DISABLED | IRQF_SHARED,
916 "[EDAC] MC err", mci); 921 "[EDAC] MC err", mci);
917 if (res < 0) { 922 if (res < 0) {
918 printk(KERN_ERR "%s: Unable to request irq %d for " 923 printk(KERN_ERR "%s: Unable to request irq %d for "
@@ -980,6 +985,9 @@ static struct of_device_id mpc85xx_mc_err_of_match[] = {
980 { 985 {
981 .compatible = "fsl,8568-memory-controller", 986 .compatible = "fsl,8568-memory-controller",
982 }, 987 },
988 {
989 .compatible = "fsl,mpc8572-memory-controller",
990 },
983 {}, 991 {},
984}; 992};
985 993
@@ -995,6 +1003,14 @@ static struct of_platform_driver mpc85xx_mc_err_driver = {
995 }, 1003 },
996}; 1004};
997 1005
1006
1007static void __init mpc85xx_mc_clear_rfxe(void *data)
1008{
1009 orig_hid1[smp_processor_id()] = mfspr(SPRN_HID1);
1010 mtspr(SPRN_HID1, (orig_hid1[smp_processor_id()] & ~0x20000));
1011}
1012
1013
998static int __init mpc85xx_mc_init(void) 1014static int __init mpc85xx_mc_init(void)
999{ 1015{
1000 int res = 0; 1016 int res = 0;
@@ -1030,19 +1046,22 @@ static int __init mpc85xx_mc_init(void)
1030 * need to clear HID1[RFXE] to disable machine check int 1046 * need to clear HID1[RFXE] to disable machine check int
1031 * so we can catch it 1047 * so we can catch it
1032 */ 1048 */
1033 if (edac_op_state == EDAC_OPSTATE_INT) { 1049 if (edac_op_state == EDAC_OPSTATE_INT)
1034 orig_hid1 = mfspr(SPRN_HID1); 1050 on_each_cpu(mpc85xx_mc_clear_rfxe, NULL, 0);
1035 mtspr(SPRN_HID1, (orig_hid1 & ~0x20000));
1036 }
1037 1051
1038 return 0; 1052 return 0;
1039} 1053}
1040 1054
1041module_init(mpc85xx_mc_init); 1055module_init(mpc85xx_mc_init);
1042 1056
1057static void __exit mpc85xx_mc_restore_hid1(void *data)
1058{
1059 mtspr(SPRN_HID1, orig_hid1[smp_processor_id()]);
1060}
1061
1043static void __exit mpc85xx_mc_exit(void) 1062static void __exit mpc85xx_mc_exit(void)
1044{ 1063{
1045 mtspr(SPRN_HID1, orig_hid1); 1064 on_each_cpu(mpc85xx_mc_restore_hid1, NULL, 0);
1046#ifdef CONFIG_PCI 1065#ifdef CONFIG_PCI
1047 of_unregister_platform_driver(&mpc85xx_pci_err_driver); 1066 of_unregister_platform_driver(&mpc85xx_pci_err_driver);
1048#endif 1067#endif
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 8d2940517c99..9112830107a5 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -67,17 +67,28 @@ static inline void desc_set_label(struct gpio_desc *d, const char *label)
67 * when setting direction, and otherwise illegal. Until board setup code 67 * when setting direction, and otherwise illegal. Until board setup code
68 * and drivers use explicit requests everywhere (which won't happen when 68 * and drivers use explicit requests everywhere (which won't happen when
69 * those calls have no teeth) we can't avoid autorequesting. This nag 69 * those calls have no teeth) we can't avoid autorequesting. This nag
70 * message should motivate switching to explicit requests... 70 * message should motivate switching to explicit requests... so should
71 * the weaker cleanup after faults, compared to gpio_request().
71 */ 72 */
72static void gpio_ensure_requested(struct gpio_desc *desc) 73static int gpio_ensure_requested(struct gpio_desc *desc, unsigned offset)
73{ 74{
74 if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) { 75 if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) {
75 pr_warning("GPIO-%d autorequested\n", (int)(desc - gpio_desc)); 76 struct gpio_chip *chip = desc->chip;
77 int gpio = chip->base + offset;
78
79 if (!try_module_get(chip->owner)) {
80 pr_err("GPIO-%d: module can't be gotten \n", gpio);
81 clear_bit(FLAG_REQUESTED, &desc->flags);
82 /* lose */
83 return -EIO;
84 }
85 pr_warning("GPIO-%d autorequested\n", gpio);
76 desc_set_label(desc, "[auto]"); 86 desc_set_label(desc, "[auto]");
77 if (!try_module_get(desc->chip->owner)) 87 /* caller must chip->request() w/o spinlock */
78 pr_err("GPIO-%d: module can't be gotten \n", 88 if (chip->request)
79 (int)(desc - gpio_desc)); 89 return 1;
80 } 90 }
91 return 0;
81} 92}
82 93
83/* caller holds gpio_lock *OR* gpio is marked as requested */ 94/* caller holds gpio_lock *OR* gpio is marked as requested */
@@ -752,6 +763,7 @@ EXPORT_SYMBOL_GPL(gpiochip_remove);
752int gpio_request(unsigned gpio, const char *label) 763int gpio_request(unsigned gpio, const char *label)
753{ 764{
754 struct gpio_desc *desc; 765 struct gpio_desc *desc;
766 struct gpio_chip *chip;
755 int status = -EINVAL; 767 int status = -EINVAL;
756 unsigned long flags; 768 unsigned long flags;
757 769
@@ -760,14 +772,15 @@ int gpio_request(unsigned gpio, const char *label)
760 if (!gpio_is_valid(gpio)) 772 if (!gpio_is_valid(gpio))
761 goto done; 773 goto done;
762 desc = &gpio_desc[gpio]; 774 desc = &gpio_desc[gpio];
763 if (desc->chip == NULL) 775 chip = desc->chip;
776 if (chip == NULL)
764 goto done; 777 goto done;
765 778
766 if (!try_module_get(desc->chip->owner)) 779 if (!try_module_get(chip->owner))
767 goto done; 780 goto done;
768 781
769 /* NOTE: gpio_request() can be called in early boot, 782 /* NOTE: gpio_request() can be called in early boot,
770 * before IRQs are enabled. 783 * before IRQs are enabled, for non-sleeping (SOC) GPIOs.
771 */ 784 */
772 785
773 if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) { 786 if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) {
@@ -775,7 +788,20 @@ int gpio_request(unsigned gpio, const char *label)
775 status = 0; 788 status = 0;
776 } else { 789 } else {
777 status = -EBUSY; 790 status = -EBUSY;
778 module_put(desc->chip->owner); 791 module_put(chip->owner);
792 }
793
794 if (chip->request) {
795 /* chip->request may sleep */
796 spin_unlock_irqrestore(&gpio_lock, flags);
797 status = chip->request(chip, gpio - chip->base);
798 spin_lock_irqsave(&gpio_lock, flags);
799
800 if (status < 0) {
801 desc_set_label(desc, NULL);
802 module_put(chip->owner);
803 clear_bit(FLAG_REQUESTED, &desc->flags);
804 }
779 } 805 }
780 806
781done: 807done:
@@ -791,6 +817,9 @@ void gpio_free(unsigned gpio)
791{ 817{
792 unsigned long flags; 818 unsigned long flags;
793 struct gpio_desc *desc; 819 struct gpio_desc *desc;
820 struct gpio_chip *chip;
821
822 might_sleep();
794 823
795 if (!gpio_is_valid(gpio)) { 824 if (!gpio_is_valid(gpio)) {
796 WARN_ON(extra_checks); 825 WARN_ON(extra_checks);
@@ -802,9 +831,17 @@ void gpio_free(unsigned gpio)
802 spin_lock_irqsave(&gpio_lock, flags); 831 spin_lock_irqsave(&gpio_lock, flags);
803 832
804 desc = &gpio_desc[gpio]; 833 desc = &gpio_desc[gpio];
805 if (desc->chip && test_and_clear_bit(FLAG_REQUESTED, &desc->flags)) { 834 chip = desc->chip;
835 if (chip && test_bit(FLAG_REQUESTED, &desc->flags)) {
836 if (chip->free) {
837 spin_unlock_irqrestore(&gpio_lock, flags);
838 might_sleep_if(extra_checks && chip->can_sleep);
839 chip->free(chip, gpio - chip->base);
840 spin_lock_irqsave(&gpio_lock, flags);
841 }
806 desc_set_label(desc, NULL); 842 desc_set_label(desc, NULL);
807 module_put(desc->chip->owner); 843 module_put(desc->chip->owner);
844 clear_bit(FLAG_REQUESTED, &desc->flags);
808 } else 845 } else
809 WARN_ON(extra_checks); 846 WARN_ON(extra_checks);
810 847
@@ -869,7 +906,9 @@ int gpio_direction_input(unsigned gpio)
869 gpio -= chip->base; 906 gpio -= chip->base;
870 if (gpio >= chip->ngpio) 907 if (gpio >= chip->ngpio)
871 goto fail; 908 goto fail;
872 gpio_ensure_requested(desc); 909 status = gpio_ensure_requested(desc, gpio);
910 if (status < 0)
911 goto fail;
873 912
874 /* now we know the gpio is valid and chip won't vanish */ 913 /* now we know the gpio is valid and chip won't vanish */
875 914
@@ -877,9 +916,22 @@ int gpio_direction_input(unsigned gpio)
877 916
878 might_sleep_if(extra_checks && chip->can_sleep); 917 might_sleep_if(extra_checks && chip->can_sleep);
879 918
919 if (status) {
920 status = chip->request(chip, gpio);
921 if (status < 0) {
922 pr_debug("GPIO-%d: chip request fail, %d\n",
923 chip->base + gpio, status);
924 /* and it's not available to anyone else ...
925 * gpio_request() is the fully clean solution.
926 */
927 goto lose;
928 }
929 }
930
880 status = chip->direction_input(chip, gpio); 931 status = chip->direction_input(chip, gpio);
881 if (status == 0) 932 if (status == 0)
882 clear_bit(FLAG_IS_OUT, &desc->flags); 933 clear_bit(FLAG_IS_OUT, &desc->flags);
934lose:
883 return status; 935 return status;
884fail: 936fail:
885 spin_unlock_irqrestore(&gpio_lock, flags); 937 spin_unlock_irqrestore(&gpio_lock, flags);
@@ -907,7 +959,9 @@ int gpio_direction_output(unsigned gpio, int value)
907 gpio -= chip->base; 959 gpio -= chip->base;
908 if (gpio >= chip->ngpio) 960 if (gpio >= chip->ngpio)
909 goto fail; 961 goto fail;
910 gpio_ensure_requested(desc); 962 status = gpio_ensure_requested(desc, gpio);
963 if (status < 0)
964 goto fail;
911 965
912 /* now we know the gpio is valid and chip won't vanish */ 966 /* now we know the gpio is valid and chip won't vanish */
913 967
@@ -915,9 +969,22 @@ int gpio_direction_output(unsigned gpio, int value)
915 969
916 might_sleep_if(extra_checks && chip->can_sleep); 970 might_sleep_if(extra_checks && chip->can_sleep);
917 971
972 if (status) {
973 status = chip->request(chip, gpio);
974 if (status < 0) {
975 pr_debug("GPIO-%d: chip request fail, %d\n",
976 chip->base + gpio, status);
977 /* and it's not available to anyone else ...
978 * gpio_request() is the fully clean solution.
979 */
980 goto lose;
981 }
982 }
983
918 status = chip->direction_output(chip, gpio, value); 984 status = chip->direction_output(chip, gpio, value);
919 if (status == 0) 985 if (status == 0)
920 set_bit(FLAG_IS_OUT, &desc->flags); 986 set_bit(FLAG_IS_OUT, &desc->flags);
987lose:
921 return status; 988 return status;
922fail: 989fail:
923 spin_unlock_irqrestore(&gpio_lock, flags); 990 spin_unlock_irqrestore(&gpio_lock, flags);
@@ -1008,6 +1075,24 @@ int __gpio_cansleep(unsigned gpio)
1008} 1075}
1009EXPORT_SYMBOL_GPL(__gpio_cansleep); 1076EXPORT_SYMBOL_GPL(__gpio_cansleep);
1010 1077
1078/**
1079 * __gpio_to_irq() - return the IRQ corresponding to a GPIO
1080 * @gpio: gpio whose IRQ will be returned (already requested)
1081 * Context: any
1082 *
1083 * This is used directly or indirectly to implement gpio_to_irq().
1084 * It returns the number of the IRQ signaled by this (input) GPIO,
1085 * or a negative errno.
1086 */
1087int __gpio_to_irq(unsigned gpio)
1088{
1089 struct gpio_chip *chip;
1090
1091 chip = gpio_to_chip(gpio);
1092 return chip->to_irq ? chip->to_irq(chip, gpio - chip->base) : -ENXIO;
1093}
1094EXPORT_SYMBOL_GPL(__gpio_to_irq);
1095
1011 1096
1012 1097
1013/* There's no value in making it easy to inline GPIO calls that may sleep. 1098/* There's no value in making it easy to inline GPIO calls that may sleep.
diff --git a/drivers/gpio/max7301.c b/drivers/gpio/max7301.c
index 39c795ad8312..8b24d784db93 100644
--- a/drivers/gpio/max7301.c
+++ b/drivers/gpio/max7301.c
@@ -255,10 +255,6 @@ static int __devinit max7301_probe(struct spi_device *spi)
255 ts->chip.dev = &spi->dev; 255 ts->chip.dev = &spi->dev;
256 ts->chip.owner = THIS_MODULE; 256 ts->chip.owner = THIS_MODULE;
257 257
258 ret = gpiochip_add(&ts->chip);
259 if (ret)
260 goto exit_destroy;
261
262 /* 258 /*
263 * tristate all pins in hardware and cache the 259 * tristate all pins in hardware and cache the
264 * register values for later use. 260 * register values for later use.
@@ -269,17 +265,19 @@ static int __devinit max7301_probe(struct spi_device *spi)
269 max7301_write(spi, 0x08 + i, 0xAA); 265 max7301_write(spi, 0x08 + i, 0xAA);
270 ts->port_config[i] = 0xAA; 266 ts->port_config[i] = 0xAA;
271 for (j = 0; j < 4; j++) { 267 for (j = 0; j < 4; j++) {
272 int idx = ts->chip.base + (i - 1) * 4 + j; 268 int offset = (i - 1) * 4 + j;
273 ret = gpio_direction_input(idx); 269 ret = max7301_direction_input(&ts->chip, offset);
274 if (ret) 270 if (ret)
275 goto exit_remove; 271 goto exit_destroy;
276 gpio_free(idx);
277 } 272 }
278 } 273 }
274
275 ret = gpiochip_add(&ts->chip);
276 if (ret)
277 goto exit_destroy;
278
279 return ret; 279 return ret;
280 280
281exit_remove:
282 gpiochip_remove(&ts->chip);
283exit_destroy: 281exit_destroy:
284 dev_set_drvdata(&spi->dev, NULL); 282 dev_set_drvdata(&spi->dev, NULL);
285 mutex_destroy(&ts->lock); 283 mutex_destroy(&ts->lock);
@@ -325,13 +323,15 @@ static int __init max7301_init(void)
325{ 323{
326 return spi_register_driver(&max7301_driver); 324 return spi_register_driver(&max7301_driver);
327} 325}
326/* register after spi postcore initcall and before
327 * subsys initcalls that may rely on these GPIOs
328 */
329subsys_initcall(max7301_init);
328 330
329static void __exit max7301_exit(void) 331static void __exit max7301_exit(void)
330{ 332{
331 spi_unregister_driver(&max7301_driver); 333 spi_unregister_driver(&max7301_driver);
332} 334}
333
334module_init(max7301_init);
335module_exit(max7301_exit); 335module_exit(max7301_exit);
336 336
337MODULE_AUTHOR("Juergen Beisert"); 337MODULE_AUTHOR("Juergen Beisert");
diff --git a/drivers/gpio/max732x.c b/drivers/gpio/max732x.c
index b51c8135ca28..55ae9a41897a 100644
--- a/drivers/gpio/max732x.c
+++ b/drivers/gpio/max732x.c
@@ -372,7 +372,10 @@ static int __init max732x_init(void)
372{ 372{
373 return i2c_add_driver(&max732x_driver); 373 return i2c_add_driver(&max732x_driver);
374} 374}
375module_init(max732x_init); 375/* register after i2c postcore initcall and before
376 * subsys initcalls that may rely on these GPIOs
377 */
378subsys_initcall(max732x_init);
376 379
377static void __exit max732x_exit(void) 380static void __exit max732x_exit(void)
378{ 381{
diff --git a/drivers/gpio/mcp23s08.c b/drivers/gpio/mcp23s08.c
index 8a1b405fefda..89c1d222e9d1 100644
--- a/drivers/gpio/mcp23s08.c
+++ b/drivers/gpio/mcp23s08.c
@@ -419,7 +419,10 @@ static int __init mcp23s08_init(void)
419{ 419{
420 return spi_register_driver(&mcp23s08_driver); 420 return spi_register_driver(&mcp23s08_driver);
421} 421}
422module_init(mcp23s08_init); 422/* register after spi postcore initcall and before
423 * subsys initcalls that may rely on these GPIOs
424 */
425subsys_initcall(mcp23s08_init);
423 426
424static void __exit mcp23s08_exit(void) 427static void __exit mcp23s08_exit(void)
425{ 428{
diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c
index cc8468692ae0..9ceeb89f1325 100644
--- a/drivers/gpio/pca953x.c
+++ b/drivers/gpio/pca953x.c
@@ -289,7 +289,10 @@ static int __init pca953x_init(void)
289{ 289{
290 return i2c_add_driver(&pca953x_driver); 290 return i2c_add_driver(&pca953x_driver);
291} 291}
292module_init(pca953x_init); 292/* register after i2c postcore initcall and before
293 * subsys initcalls that may rely on these GPIOs
294 */
295subsys_initcall(pca953x_init);
293 296
294static void __exit pca953x_exit(void) 297static void __exit pca953x_exit(void)
295{ 298{
diff --git a/drivers/gpio/pcf857x.c b/drivers/gpio/pcf857x.c
index fc9c6ae739ee..4bc2070dd4a1 100644
--- a/drivers/gpio/pcf857x.c
+++ b/drivers/gpio/pcf857x.c
@@ -351,7 +351,10 @@ static int __init pcf857x_init(void)
351{ 351{
352 return i2c_add_driver(&pcf857x_driver); 352 return i2c_add_driver(&pcf857x_driver);
353} 353}
354module_init(pcf857x_init); 354/* register after i2c postcore initcall and before
355 * subsys initcalls that may rely on these GPIOs
356 */
357subsys_initcall(pcf857x_init);
355 358
356static void __exit pcf857x_exit(void) 359static void __exit pcf857x_exit(void)
357{ 360{
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 88974342933c..9ac4720e647b 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -517,7 +517,7 @@ static int i915_dispatch_flip(struct drm_device * dev)
517 RING_LOCALS; 517 RING_LOCALS;
518 518
519 DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", 519 DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n",
520 __FUNCTION__, 520 __func__,
521 dev_priv->current_page, 521 dev_priv->current_page,
522 dev_priv->sarea_priv->pf_current_page); 522 dev_priv->sarea_priv->pf_current_page);
523 523
@@ -642,7 +642,7 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
642static int i915_flip_bufs(struct drm_device *dev, void *data, 642static int i915_flip_bufs(struct drm_device *dev, void *data,
643 struct drm_file *file_priv) 643 struct drm_file *file_priv)
644{ 644{
645 DRM_DEBUG("%s\n", __FUNCTION__); 645 DRM_DEBUG("%s\n", __func__);
646 646
647 LOCK_TEST_WITH_RETURN(dev, file_priv); 647 LOCK_TEST_WITH_RETURN(dev, file_priv);
648 648
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index da64108de775..f5999a91614e 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -17,25 +17,6 @@ config HID
17 tristate "Generic HID support" 17 tristate "Generic HID support"
18 depends on INPUT 18 depends on INPUT
19 default y 19 default y
20 select HID_A4TECH if !EMBEDDED
21 select HID_APPLE if !EMBEDDED
22 select HID_BELKIN if !EMBEDDED
23 select HID_BRIGHT if !EMBEDDED
24 select HID_CHERRY if !EMBEDDED
25 select HID_CHICONY if !EMBEDDED
26 select HID_CYPRESS if !EMBEDDED
27 select HID_DELL if !EMBEDDED
28 select HID_EZKEY if !EMBEDDED
29 select HID_GYRATION if !EMBEDDED
30 select HID_LOGITECH if !EMBEDDED
31 select HID_MICROSOFT if !EMBEDDED
32 select HID_MONTEREY if !EMBEDDED
33 select HID_PANTHERLORD if !EMBEDDED
34 select HID_PETALYNX if !EMBEDDED
35 select HID_SAMSUNG if !EMBEDDED
36 select HID_SONY if !EMBEDDED
37 select HID_SUNPLUS if !EMBEDDED
38
39 ---help--- 20 ---help---
40 A human interface device (HID) is a type of computer device that 21 A human interface device (HID) is a type of computer device that
41 interacts directly with and takes input from humans. The term "HID" 22 interacts directly with and takes input from humans. The term "HID"
@@ -102,89 +83,86 @@ config HID_COMPAT
102 If unsure, say Y. 83 If unsure, say Y.
103 84
104config HID_A4TECH 85config HID_A4TECH
105 tristate "A4 tech" 86 tristate "A4 tech" if EMBEDDED
106 default m
107 depends on USB_HID 87 depends on USB_HID
88 default y
108 ---help--- 89 ---help---
109 Support for A4 tech X5 and WOP-35 / Trust 450L mice. 90 Support for A4 tech X5 and WOP-35 / Trust 450L mice.
110 91
111config HID_APPLE 92config HID_APPLE
112 tristate "Apple" 93 tristate "Apple" if EMBEDDED
113 default m
114 depends on (USB_HID || BT_HIDP) 94 depends on (USB_HID || BT_HIDP)
95 default y
115 ---help--- 96 ---help---
116 Support for some Apple devices which less or more break 97 Support for some Apple devices which less or more break
117 HID specification. 98 HID specification.
118 99
119 Say Y here if you want support for the special keys (Fn, Numlock) on 100 Say Y here if you want support for keyboards of Apple iBooks, PowerBooks,
120 Apple iBooks, PowerBooks, MacBooks, MacBook Pros and aluminum USB 101 MacBooks, MacBook Pros and Apple Aluminum.
121 keyboards.
122
123 If unsure, say M.
124 102
125config HID_BELKIN 103config HID_BELKIN
126 tristate "Belkin" 104 tristate "Belkin" if EMBEDDED
127 default m
128 depends on USB_HID 105 depends on USB_HID
106 default y
129 ---help--- 107 ---help---
130 Support for Belkin Flip KVM and Wireless keyboard. 108 Support for Belkin Flip KVM and Wireless keyboard.
131 109
132config HID_BRIGHT 110config HID_BRIGHT
133 tristate "Bright" 111 tristate "Bright" if EMBEDDED
134 default m
135 depends on USB_HID 112 depends on USB_HID
113 default y
136 ---help--- 114 ---help---
137 Support for Bright ABNT-2 keyboard. 115 Support for Bright ABNT-2 keyboard.
138 116
139config HID_CHERRY 117config HID_CHERRY
140 tristate "Cherry" 118 tristate "Cherry" if EMBEDDED
141 default m
142 depends on USB_HID 119 depends on USB_HID
120 default y
143 ---help--- 121 ---help---
144 Support for Cherry Cymotion. 122 Support for Cherry Cymotion keyboard.
145 123
146config HID_CHICONY 124config HID_CHICONY
147 tristate "Chicony" 125 tristate "Chicony" if EMBEDDED
148 default m
149 depends on USB_HID 126 depends on USB_HID
127 default y
150 ---help--- 128 ---help---
151 Support for Chicony Tactical pad. 129 Support for Chicony Tactical pad.
152 130
153config HID_CYPRESS 131config HID_CYPRESS
154 tristate "Cypress" 132 tristate "Cypress" if EMBEDDED
155 default m
156 depends on USB_HID 133 depends on USB_HID
134 default y
157 ---help--- 135 ---help---
158 Support for Cypress mouse and barcodes. 136 Support for cypress mouse and barcode readers.
159 137
160config HID_DELL 138config HID_DELL
161 tristate "Dell" 139 tristate "Dell" if EMBEDDED
162 default m
163 depends on USB_HID 140 depends on USB_HID
141 default y
164 ---help--- 142 ---help---
165 Support for Dell W7658. 143 Support for quirky Dell HID hardware that require
144 special LED handling (W7658 and SK8115 models)
166 145
167config HID_EZKEY 146config HID_EZKEY
168 tristate "Ezkey" 147 tristate "Ezkey" if EMBEDDED
169 default m
170 depends on USB_HID 148 depends on USB_HID
149 default y
171 ---help--- 150 ---help---
172 Support for Ezkey mouse and barcodes. 151 Support for Ezkey BTC 8193 keyboard.
173 152
174config HID_GYRATION 153config HID_GYRATION
175 tristate "Gyration" 154 tristate "Gyration" if EMBEDDED
176 default m
177 depends on USB_HID 155 depends on USB_HID
156 default y
178 ---help--- 157 ---help---
179 Support for Gyration remote. 158 Support for Gyration remote control.
180 159
181config HID_LOGITECH 160config HID_LOGITECH
182 tristate "Logitech" 161 tristate "Logitech" if EMBEDDED
183 default m
184 depends on USB_HID 162 depends on USB_HID
163 default y
185 ---help--- 164 ---help---
186 Support for some Logitech devices which breaks less or more 165 Support for Logitech devices that are not fully compliant with HID standard.
187 HID specification.
188 166
189config LOGITECH_FF 167config LOGITECH_FF
190 bool "Logitech force feedback" 168 bool "Logitech force feedback"
@@ -211,28 +189,26 @@ config LOGIRUMBLEPAD2_FF
211 Rumblepad 2 devices. 189 Rumblepad 2 devices.
212 190
213config HID_MICROSOFT 191config HID_MICROSOFT
214 tristate "Microsoft" 192 tristate "Microsoft" if EMBEDDED
215 default m
216 depends on USB_HID 193 depends on USB_HID
194 default y
217 ---help--- 195 ---help---
218 Support for some Microsoft devices which breaks less or more 196 Support for Microsoft devices that are not fully compliant with HID standard.
219 HID specification.
220 197
221config HID_MONTEREY 198config HID_MONTEREY
222 tristate "Monterey" 199 tristate "Monterey" if EMBEDDED
223 default m
224 depends on USB_HID 200 depends on USB_HID
201 default y
225 ---help--- 202 ---help---
226 Support for Monterey Genius KB29E. 203 Support for Monterey Genius KB29E.
227 204
228config HID_PANTHERLORD 205config HID_PANTHERLORD
229 tristate "Pantherlord devices support" 206 tristate "Pantherlord devices support" if EMBEDDED
230 default m
231 depends on USB_HID 207 depends on USB_HID
208 default y
232 ---help--- 209 ---help---
233 Support for PantherLord/GreenAsia based device support. 210 Support for PantherLord/GreenAsia based device support.
234 211
235
236config PANTHERLORD_FF 212config PANTHERLORD_FF
237 bool "Pantherlord force feedback support" 213 bool "Pantherlord force feedback support"
238 depends on HID_PANTHERLORD 214 depends on HID_PANTHERLORD
@@ -242,32 +218,32 @@ config PANTHERLORD_FF
242 or adapter and want to enable force feedback support for it. 218 or adapter and want to enable force feedback support for it.
243 219
244config HID_PETALYNX 220config HID_PETALYNX
245 tristate "Petalynx" 221 tristate "Petalynx" if EMBEDDED
246 default m
247 depends on USB_HID 222 depends on USB_HID
223 default y
248 ---help--- 224 ---help---
249 Support for Petalynx Maxter remote. 225 Support for Petalynx Maxter remote control.
250 226
251config HID_SAMSUNG 227config HID_SAMSUNG
252 tristate "Samsung" 228 tristate "Samsung" if EMBEDDED
253 default m
254 depends on USB_HID 229 depends on USB_HID
230 default y
255 ---help--- 231 ---help---
256 Support for Samsung IR remote. 232 Support for Samsung InfraRed remote control.
257 233
258config HID_SONY 234config HID_SONY
259 tristate "Sony" 235 tristate "Sony" if EMBEDDED
260 default m
261 depends on USB_HID 236 depends on USB_HID
237 default y
262 ---help--- 238 ---help---
263 Support for Sony PS3 controller. 239 Support for Sony PS3 controller.
264 240
265config HID_SUNPLUS 241config HID_SUNPLUS
266 tristate "Sunplus" 242 tristate "Sunplus" if EMBEDDED
267 default m
268 depends on USB_HID 243 depends on USB_HID
244 default y
269 ---help--- 245 ---help---
270 Support for Sunplus WDesktop input device. 246 Support for Sunplus wireless desktop.
271 247
272config THRUSTMASTER_FF 248config THRUSTMASTER_FF
273 tristate "ThrustMaster devices support" 249 tristate "ThrustMaster devices support"
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 8a7d9dbb4d07..721a36d97582 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1518,6 +1518,8 @@ static const struct hid_device_id hid_ignore_list[] = {
1518 { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0003) }, 1518 { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0003) },
1519 { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0004) }, 1519 { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0004) },
1520 { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD) }, 1520 { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD) },
1521 { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD2) },
1522 { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD3) },
1521 { HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY1) }, 1523 { HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY1) },
1522 { HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY2) }, 1524 { HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY2) },
1523 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) }, 1525 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) },
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index aad9ed1b406e..d9a1ba920c23 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -354,6 +354,8 @@
354 354
355#define USB_VENDOR_ID_SOUNDGRAPH 0x15c2 355#define USB_VENDOR_ID_SOUNDGRAPH 0x15c2
356#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD 0x0038 356#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD 0x0038
357#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD2 0x0036
358#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD3 0x0034
357 359
358#define USB_VENDOR_ID_SUN 0x0430 360#define USB_VENDOR_ID_SUN 0x0430
359#define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab 361#define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index e7eb7bf9ddec..608038d64f81 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -589,11 +589,16 @@ omap_i2c_probe(struct platform_device *pdev)
589 589
590 dev->dev = &pdev->dev; 590 dev->dev = &pdev->dev;
591 dev->irq = irq->start; 591 dev->irq = irq->start;
592 dev->base = (void __iomem *) IO_ADDRESS(mem->start); 592 dev->base = ioremap(mem->start, mem->end - mem->start + 1);
593 if (!dev->base) {
594 r = -ENOMEM;
595 goto err_free_mem;
596 }
597
593 platform_set_drvdata(pdev, dev); 598 platform_set_drvdata(pdev, dev);
594 599
595 if ((r = omap_i2c_get_clocks(dev)) != 0) 600 if ((r = omap_i2c_get_clocks(dev)) != 0)
596 goto err_free_mem; 601 goto err_iounmap;
597 602
598 omap_i2c_unidle(dev); 603 omap_i2c_unidle(dev);
599 604
@@ -640,6 +645,8 @@ err_unuse_clocks:
640 omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); 645 omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
641 omap_i2c_idle(dev); 646 omap_i2c_idle(dev);
642 omap_i2c_put_clocks(dev); 647 omap_i2c_put_clocks(dev);
648err_iounmap:
649 iounmap(dev->base);
643err_free_mem: 650err_free_mem:
644 platform_set_drvdata(pdev, NULL); 651 platform_set_drvdata(pdev, NULL);
645 kfree(dev); 652 kfree(dev);
@@ -661,6 +668,7 @@ omap_i2c_remove(struct platform_device *pdev)
661 i2c_del_adapter(&dev->adapter); 668 i2c_del_adapter(&dev->adapter);
662 omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); 669 omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
663 omap_i2c_put_clocks(dev); 670 omap_i2c_put_clocks(dev);
671 iounmap(dev->base);
664 kfree(dev); 672 kfree(dev);
665 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 673 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
666 release_mem_region(mem->start, (mem->end - mem->start) + 1); 674 release_mem_region(mem->start, (mem->end - mem->start) + 1);
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 6c6dd2facede..74a369a6116f 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -4,7 +4,7 @@
4 4
5# Select HAVE_IDE if IDE is supported 5# Select HAVE_IDE if IDE is supported
6config HAVE_IDE 6config HAVE_IDE
7 def_bool n 7 bool
8 8
9menuconfig IDE 9menuconfig IDE
10 tristate "ATA/ATAPI/MFM/RLL support" 10 tristate "ATA/ATAPI/MFM/RLL support"
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
index 078e4eed0894..2880eaae157a 100644
--- a/drivers/input/gameport/gameport.c
+++ b/drivers/input/gameport/gameport.c
@@ -231,6 +231,7 @@ static void gameport_find_driver(struct gameport *gameport)
231enum gameport_event_type { 231enum gameport_event_type {
232 GAMEPORT_REGISTER_PORT, 232 GAMEPORT_REGISTER_PORT,
233 GAMEPORT_REGISTER_DRIVER, 233 GAMEPORT_REGISTER_DRIVER,
234 GAMEPORT_ATTACH_DRIVER,
234}; 235};
235 236
236struct gameport_event { 237struct gameport_event {
@@ -245,11 +246,12 @@ static LIST_HEAD(gameport_event_list);
245static DECLARE_WAIT_QUEUE_HEAD(gameport_wait); 246static DECLARE_WAIT_QUEUE_HEAD(gameport_wait);
246static struct task_struct *gameport_task; 247static struct task_struct *gameport_task;
247 248
248static void gameport_queue_event(void *object, struct module *owner, 249static int gameport_queue_event(void *object, struct module *owner,
249 enum gameport_event_type event_type) 250 enum gameport_event_type event_type)
250{ 251{
251 unsigned long flags; 252 unsigned long flags;
252 struct gameport_event *event; 253 struct gameport_event *event;
254 int retval = 0;
253 255
254 spin_lock_irqsave(&gameport_event_lock, flags); 256 spin_lock_irqsave(&gameport_event_lock, flags);
255 257
@@ -268,24 +270,34 @@ static void gameport_queue_event(void *object, struct module *owner,
268 } 270 }
269 } 271 }
270 272
271 if ((event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC))) { 273 event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC);
272 if (!try_module_get(owner)) { 274 if (!event) {
273 printk(KERN_WARNING "gameport: Can't get module reference, dropping event %d\n", event_type); 275 printk(KERN_ERR
274 kfree(event); 276 "gameport: Not enough memory to queue event %d\n",
275 goto out; 277 event_type);
276 } 278 retval = -ENOMEM;
277 279 goto out;
278 event->type = event_type; 280 }
279 event->object = object;
280 event->owner = owner;
281 281
282 list_add_tail(&event->node, &gameport_event_list); 282 if (!try_module_get(owner)) {
283 wake_up(&gameport_wait); 283 printk(KERN_WARNING
284 } else { 284 "gameport: Can't get module reference, dropping event %d\n",
285 printk(KERN_ERR "gameport: Not enough memory to queue event %d\n", event_type); 285 event_type);
286 kfree(event);
287 retval = -EINVAL;
288 goto out;
286 } 289 }
290
291 event->type = event_type;
292 event->object = object;
293 event->owner = owner;
294
295 list_add_tail(&event->node, &gameport_event_list);
296 wake_up(&gameport_wait);
297
287out: 298out:
288 spin_unlock_irqrestore(&gameport_event_lock, flags); 299 spin_unlock_irqrestore(&gameport_event_lock, flags);
300 return retval;
289} 301}
290 302
291static void gameport_free_event(struct gameport_event *event) 303static void gameport_free_event(struct gameport_event *event)
@@ -378,9 +390,10 @@ static void gameport_handle_event(void)
378} 390}
379 391
380/* 392/*
381 * Remove all events that have been submitted for a given gameport port. 393 * Remove all events that have been submitted for a given object,
394 * be it a gameport port or a driver.
382 */ 395 */
383static void gameport_remove_pending_events(struct gameport *gameport) 396static void gameport_remove_pending_events(void *object)
384{ 397{
385 struct list_head *node, *next; 398 struct list_head *node, *next;
386 struct gameport_event *event; 399 struct gameport_event *event;
@@ -390,7 +403,7 @@ static void gameport_remove_pending_events(struct gameport *gameport)
390 403
391 list_for_each_safe(node, next, &gameport_event_list) { 404 list_for_each_safe(node, next, &gameport_event_list) {
392 event = list_entry(node, struct gameport_event, node); 405 event = list_entry(node, struct gameport_event, node);
393 if (event->object == gameport) { 406 if (event->object == object) {
394 list_del_init(node); 407 list_del_init(node);
395 gameport_free_event(event); 408 gameport_free_event(event);
396 } 409 }
@@ -705,10 +718,40 @@ static void gameport_add_driver(struct gameport_driver *drv)
705 drv->driver.name, error); 718 drv->driver.name, error);
706} 719}
707 720
708void __gameport_register_driver(struct gameport_driver *drv, struct module *owner) 721int __gameport_register_driver(struct gameport_driver *drv, struct module *owner,
722 const char *mod_name)
709{ 723{
724 int error;
725
710 drv->driver.bus = &gameport_bus; 726 drv->driver.bus = &gameport_bus;
711 gameport_queue_event(drv, owner, GAMEPORT_REGISTER_DRIVER); 727 drv->driver.owner = owner;
728 drv->driver.mod_name = mod_name;
729
730 /*
731 * Temporarily disable automatic binding because probing
732 * takes long time and we are better off doing it in kgameportd
733 */
734 drv->ignore = 1;
735
736 error = driver_register(&drv->driver);
737 if (error) {
738 printk(KERN_ERR
739 "gameport: driver_register() failed for %s, error: %d\n",
740 drv->driver.name, error);
741 return error;
742 }
743
744 /*
745 * Reset ignore flag and let kgameportd bind the driver to free ports
746 */
747 drv->ignore = 0;
748 error = gameport_queue_event(drv, NULL, GAMEPORT_ATTACH_DRIVER);
749 if (error) {
750 driver_unregister(&drv->driver);
751 return error;
752 }
753
754 return 0;
712} 755}
713 756
714void gameport_unregister_driver(struct gameport_driver *drv) 757void gameport_unregister_driver(struct gameport_driver *drv)
@@ -716,7 +759,9 @@ void gameport_unregister_driver(struct gameport_driver *drv)
716 struct gameport *gameport; 759 struct gameport *gameport;
717 760
718 mutex_lock(&gameport_mutex); 761 mutex_lock(&gameport_mutex);
762
719 drv->ignore = 1; /* so gameport_find_driver ignores it */ 763 drv->ignore = 1; /* so gameport_find_driver ignores it */
764 gameport_remove_pending_events(drv);
720 765
721start_over: 766start_over:
722 list_for_each_entry(gameport, &gameport_list, node) { 767 list_for_each_entry(gameport, &gameport_list, node) {
@@ -729,6 +774,7 @@ start_over:
729 } 774 }
730 775
731 driver_unregister(&drv->driver); 776 driver_unregister(&drv->driver);
777
732 mutex_unlock(&gameport_mutex); 778 mutex_unlock(&gameport_mutex);
733} 779}
734 780
diff --git a/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c
index 92498d470b1f..6489f4010c4f 100644
--- a/drivers/input/joystick/a3d.c
+++ b/drivers/input/joystick/a3d.c
@@ -414,8 +414,7 @@ static struct gameport_driver a3d_drv = {
414 414
415static int __init a3d_init(void) 415static int __init a3d_init(void)
416{ 416{
417 gameport_register_driver(&a3d_drv); 417 return gameport_register_driver(&a3d_drv);
418 return 0;
419} 418}
420 419
421static void __exit a3d_exit(void) 420static void __exit a3d_exit(void)
diff --git a/drivers/input/joystick/adi.c b/drivers/input/joystick/adi.c
index d1ca8a14950f..89c4c084d4ad 100644
--- a/drivers/input/joystick/adi.c
+++ b/drivers/input/joystick/adi.c
@@ -572,8 +572,7 @@ static struct gameport_driver adi_drv = {
572 572
573static int __init adi_init(void) 573static int __init adi_init(void)
574{ 574{
575 gameport_register_driver(&adi_drv); 575 return gameport_register_driver(&adi_drv);
576 return 0;
577} 576}
578 577
579static void __exit adi_exit(void) 578static void __exit adi_exit(void)
diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c
index 708c5ae13b24..356b3a25efa2 100644
--- a/drivers/input/joystick/analog.c
+++ b/drivers/input/joystick/analog.c
@@ -761,9 +761,7 @@ static struct gameport_driver analog_drv = {
761static int __init analog_init(void) 761static int __init analog_init(void)
762{ 762{
763 analog_parse_options(); 763 analog_parse_options();
764 gameport_register_driver(&analog_drv); 764 return gameport_register_driver(&analog_drv);
765
766 return 0;
767} 765}
768 766
769static void __exit analog_exit(void) 767static void __exit analog_exit(void)
diff --git a/drivers/input/joystick/cobra.c b/drivers/input/joystick/cobra.c
index 639b975a8ed7..3497b87c3d05 100644
--- a/drivers/input/joystick/cobra.c
+++ b/drivers/input/joystick/cobra.c
@@ -263,8 +263,7 @@ static struct gameport_driver cobra_drv = {
263 263
264static int __init cobra_init(void) 264static int __init cobra_init(void)
265{ 265{
266 gameport_register_driver(&cobra_drv); 266 return gameport_register_driver(&cobra_drv);
267 return 0;
268} 267}
269 268
270static void __exit cobra_exit(void) 269static void __exit cobra_exit(void)
diff --git a/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c
index cb6eef1f2d99..67c207f5b1a1 100644
--- a/drivers/input/joystick/gf2k.c
+++ b/drivers/input/joystick/gf2k.c
@@ -375,8 +375,7 @@ static struct gameport_driver gf2k_drv = {
375 375
376static int __init gf2k_init(void) 376static int __init gf2k_init(void)
377{ 377{
378 gameport_register_driver(&gf2k_drv); 378 return gameport_register_driver(&gf2k_drv);
379 return 0;
380} 379}
381 380
382static void __exit gf2k_exit(void) 381static void __exit gf2k_exit(void)
diff --git a/drivers/input/joystick/grip.c b/drivers/input/joystick/grip.c
index 684e07cfccc8..fc55899ba6c5 100644
--- a/drivers/input/joystick/grip.c
+++ b/drivers/input/joystick/grip.c
@@ -426,8 +426,7 @@ static struct gameport_driver grip_drv = {
426 426
427static int __init grip_init(void) 427static int __init grip_init(void)
428{ 428{
429 gameport_register_driver(&grip_drv); 429 return gameport_register_driver(&grip_drv);
430 return 0;
431} 430}
432 431
433static void __exit grip_exit(void) 432static void __exit grip_exit(void)
diff --git a/drivers/input/joystick/grip_mp.c b/drivers/input/joystick/grip_mp.c
index 8279481b16e7..2d47baf47769 100644
--- a/drivers/input/joystick/grip_mp.c
+++ b/drivers/input/joystick/grip_mp.c
@@ -689,8 +689,7 @@ static struct gameport_driver grip_drv = {
689 689
690static int __init grip_init(void) 690static int __init grip_init(void)
691{ 691{
692 gameport_register_driver(&grip_drv); 692 return gameport_register_driver(&grip_drv);
693 return 0;
694} 693}
695 694
696static void __exit grip_exit(void) 695static void __exit grip_exit(void)
diff --git a/drivers/input/joystick/guillemot.c b/drivers/input/joystick/guillemot.c
index 25ec3fad9f27..4058d4b272fe 100644
--- a/drivers/input/joystick/guillemot.c
+++ b/drivers/input/joystick/guillemot.c
@@ -283,8 +283,7 @@ static struct gameport_driver guillemot_drv = {
283 283
284static int __init guillemot_init(void) 284static int __init guillemot_init(void)
285{ 285{
286 gameport_register_driver(&guillemot_drv); 286 return gameport_register_driver(&guillemot_drv);
287 return 0;
288} 287}
289 288
290static void __exit guillemot_exit(void) 289static void __exit guillemot_exit(void)
diff --git a/drivers/input/joystick/interact.c b/drivers/input/joystick/interact.c
index 8c3290b68205..2478289aeeea 100644
--- a/drivers/input/joystick/interact.c
+++ b/drivers/input/joystick/interact.c
@@ -317,8 +317,7 @@ static struct gameport_driver interact_drv = {
317 317
318static int __init interact_init(void) 318static int __init interact_init(void)
319{ 319{
320 gameport_register_driver(&interact_drv); 320 return gameport_register_driver(&interact_drv);
321 return 0;
322} 321}
323 322
324static void __exit interact_exit(void) 323static void __exit interact_exit(void)
diff --git a/drivers/input/joystick/joydump.c b/drivers/input/joystick/joydump.c
index 2a1b82c8b31c..cd894a0564a2 100644
--- a/drivers/input/joystick/joydump.c
+++ b/drivers/input/joystick/joydump.c
@@ -161,8 +161,7 @@ static struct gameport_driver joydump_drv = {
161 161
162static int __init joydump_init(void) 162static int __init joydump_init(void)
163{ 163{
164 gameport_register_driver(&joydump_drv); 164 return gameport_register_driver(&joydump_drv);
165 return 0;
166} 165}
167 166
168static void __exit joydump_exit(void) 167static void __exit joydump_exit(void)
diff --git a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c
index 7b4865fdee54..ca13a6bec33e 100644
--- a/drivers/input/joystick/sidewinder.c
+++ b/drivers/input/joystick/sidewinder.c
@@ -818,8 +818,7 @@ static struct gameport_driver sw_drv = {
818 818
819static int __init sw_init(void) 819static int __init sw_init(void)
820{ 820{
821 gameport_register_driver(&sw_drv); 821 return gameport_register_driver(&sw_drv);
822 return 0;
823} 822}
824 823
825static void __exit sw_exit(void) 824static void __exit sw_exit(void)
diff --git a/drivers/input/joystick/tmdc.c b/drivers/input/joystick/tmdc.c
index 60c37bcb938d..d6c609807115 100644
--- a/drivers/input/joystick/tmdc.c
+++ b/drivers/input/joystick/tmdc.c
@@ -438,8 +438,7 @@ static struct gameport_driver tmdc_drv = {
438 438
439static int __init tmdc_init(void) 439static int __init tmdc_init(void)
440{ 440{
441 gameport_register_driver(&tmdc_drv); 441 return gameport_register_driver(&tmdc_drv);
442 return 0;
443} 442}
444 443
445static void __exit tmdc_exit(void) 444static void __exit tmdc_exit(void)
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 6791be81eb29..839d1c9622f6 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -455,10 +455,10 @@ static void xpad_bulk_out(struct urb *urb)
455 case -ENOENT: 455 case -ENOENT:
456 case -ESHUTDOWN: 456 case -ESHUTDOWN:
457 /* this urb is terminated, clean up */ 457 /* this urb is terminated, clean up */
458 dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); 458 dbg("%s - urb shutting down with status: %d", __func__, urb->status);
459 break; 459 break;
460 default: 460 default:
461 dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); 461 dbg("%s - nonzero urb status received: %d", __func__, urb->status);
462 } 462 }
463} 463}
464 464
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index b1ce10f50bcf..22016ca15351 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -834,10 +834,10 @@ static void atkbd_disconnect(struct serio *serio)
834} 834}
835 835
836/* 836/*
837 * Most special keys (Fn+F?) on Dell Latitudes do not generate release 837 * Most special keys (Fn+F?) on Dell laptops do not generate release
838 * events so we have to do it ourselves. 838 * events so we have to do it ourselves.
839 */ 839 */
840static void atkbd_latitude_keymap_fixup(struct atkbd *atkbd) 840static void atkbd_dell_laptop_keymap_fixup(struct atkbd *atkbd)
841{ 841{
842 const unsigned int forced_release_keys[] = { 842 const unsigned int forced_release_keys[] = {
843 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93, 843 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93,
@@ -1207,15 +1207,13 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun
1207{ 1207{
1208 struct input_dev *old_dev, *new_dev; 1208 struct input_dev *old_dev, *new_dev;
1209 unsigned long value; 1209 unsigned long value;
1210 char *rest;
1211 int err; 1210 int err;
1212 unsigned char old_extra, old_set; 1211 unsigned char old_extra, old_set;
1213 1212
1214 if (!atkbd->write) 1213 if (!atkbd->write)
1215 return -EIO; 1214 return -EIO;
1216 1215
1217 value = simple_strtoul(buf, &rest, 10); 1216 if (strict_strtoul(buf, 10, &value) || value > 1)
1218 if (*rest || value > 1)
1219 return -EINVAL; 1217 return -EINVAL;
1220 1218
1221 if (atkbd->extra != value) { 1219 if (atkbd->extra != value) {
@@ -1264,12 +1262,10 @@ static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t cou
1264{ 1262{
1265 struct input_dev *old_dev, *new_dev; 1263 struct input_dev *old_dev, *new_dev;
1266 unsigned long value; 1264 unsigned long value;
1267 char *rest;
1268 int err; 1265 int err;
1269 unsigned char old_scroll; 1266 unsigned char old_scroll;
1270 1267
1271 value = simple_strtoul(buf, &rest, 10); 1268 if (strict_strtoul(buf, 10, &value) || value > 1)
1272 if (*rest || value > 1)
1273 return -EINVAL; 1269 return -EINVAL;
1274 1270
1275 if (atkbd->scroll != value) { 1271 if (atkbd->scroll != value) {
@@ -1310,15 +1306,13 @@ static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count)
1310{ 1306{
1311 struct input_dev *old_dev, *new_dev; 1307 struct input_dev *old_dev, *new_dev;
1312 unsigned long value; 1308 unsigned long value;
1313 char *rest;
1314 int err; 1309 int err;
1315 unsigned char old_set, old_extra; 1310 unsigned char old_set, old_extra;
1316 1311
1317 if (!atkbd->write) 1312 if (!atkbd->write)
1318 return -EIO; 1313 return -EIO;
1319 1314
1320 value = simple_strtoul(buf, &rest, 10); 1315 if (strict_strtoul(buf, 10, &value) || (value != 2 && value != 3))
1321 if (*rest || (value != 2 && value != 3))
1322 return -EINVAL; 1316 return -EINVAL;
1323 1317
1324 if (atkbd->set != value) { 1318 if (atkbd->set != value) {
@@ -1361,15 +1355,13 @@ static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t
1361{ 1355{
1362 struct input_dev *old_dev, *new_dev; 1356 struct input_dev *old_dev, *new_dev;
1363 unsigned long value; 1357 unsigned long value;
1364 char *rest;
1365 int err; 1358 int err;
1366 unsigned char old_softrepeat, old_softraw; 1359 unsigned char old_softrepeat, old_softraw;
1367 1360
1368 if (!atkbd->write) 1361 if (!atkbd->write)
1369 return -EIO; 1362 return -EIO;
1370 1363
1371 value = simple_strtoul(buf, &rest, 10); 1364 if (strict_strtoul(buf, 10, &value) || value > 1)
1372 if (*rest || value > 1)
1373 return -EINVAL; 1365 return -EINVAL;
1374 1366
1375 if (atkbd->softrepeat != value) { 1367 if (atkbd->softrepeat != value) {
@@ -1413,12 +1405,10 @@ static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t co
1413{ 1405{
1414 struct input_dev *old_dev, *new_dev; 1406 struct input_dev *old_dev, *new_dev;
1415 unsigned long value; 1407 unsigned long value;
1416 char *rest;
1417 int err; 1408 int err;
1418 unsigned char old_softraw; 1409 unsigned char old_softraw;
1419 1410
1420 value = simple_strtoul(buf, &rest, 10); 1411 if (strict_strtoul(buf, 10, &value) || value > 1)
1421 if (*rest || value > 1)
1422 return -EINVAL; 1412 return -EINVAL;
1423 1413
1424 if (atkbd->softraw != value) { 1414 if (atkbd->softraw != value) {
@@ -1461,13 +1451,13 @@ static int __init atkbd_setup_fixup(const struct dmi_system_id *id)
1461 1451
1462static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { 1452static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
1463 { 1453 {
1464 .ident = "Dell Latitude series", 1454 .ident = "Dell Laptop",
1465 .matches = { 1455 .matches = {
1466 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 1456 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1467 DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"), 1457 DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */
1468 }, 1458 },
1469 .callback = atkbd_setup_fixup, 1459 .callback = atkbd_setup_fixup,
1470 .driver_data = atkbd_latitude_keymap_fixup, 1460 .driver_data = atkbd_dell_laptop_keymap_fixup,
1471 }, 1461 },
1472 { 1462 {
1473 .ident = "HP 2133", 1463 .ident = "HP 2133",
diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c
index e348cfccc17a..19284016e0f4 100644
--- a/drivers/input/keyboard/bf54x-keys.c
+++ b/drivers/input/keyboard/bf54x-keys.c
@@ -8,7 +8,7 @@
8 * 8 *
9 * 9 *
10 * Modified: 10 * Modified:
11 * Copyright 2007 Analog Devices Inc. 11 * Copyright 2007-2008 Analog Devices Inc.
12 * 12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/ 13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 * 14 *
@@ -81,6 +81,9 @@ struct bf54x_kpad {
81 unsigned short *keycode; 81 unsigned short *keycode;
82 struct timer_list timer; 82 struct timer_list timer;
83 unsigned int keyup_test_jiffies; 83 unsigned int keyup_test_jiffies;
84 unsigned short kpad_msel;
85 unsigned short kpad_prescale;
86 unsigned short kpad_ctl;
84}; 87};
85 88
86static inline int bfin_kpad_find_key(struct bf54x_kpad *bf54x_kpad, 89static inline int bfin_kpad_find_key(struct bf54x_kpad *bf54x_kpad,
@@ -360,6 +363,10 @@ static int bfin_kpad_suspend(struct platform_device *pdev, pm_message_t state)
360{ 363{
361 struct bf54x_kpad *bf54x_kpad = platform_get_drvdata(pdev); 364 struct bf54x_kpad *bf54x_kpad = platform_get_drvdata(pdev);
362 365
366 bf54x_kpad->kpad_msel = bfin_read_KPAD_MSEL();
367 bf54x_kpad->kpad_prescale = bfin_read_KPAD_PRESCALE();
368 bf54x_kpad->kpad_ctl = bfin_read_KPAD_CTL();
369
363 if (device_may_wakeup(&pdev->dev)) 370 if (device_may_wakeup(&pdev->dev))
364 enable_irq_wake(bf54x_kpad->irq); 371 enable_irq_wake(bf54x_kpad->irq);
365 372
@@ -370,6 +377,10 @@ static int bfin_kpad_resume(struct platform_device *pdev)
370{ 377{
371 struct bf54x_kpad *bf54x_kpad = platform_get_drvdata(pdev); 378 struct bf54x_kpad *bf54x_kpad = platform_get_drvdata(pdev);
372 379
380 bfin_write_KPAD_MSEL(bf54x_kpad->kpad_msel);
381 bfin_write_KPAD_PRESCALE(bf54x_kpad->kpad_prescale);
382 bfin_write_KPAD_CTL(bf54x_kpad->kpad_ctl);
383
373 if (device_may_wakeup(&pdev->dev)) 384 if (device_may_wakeup(&pdev->dev))
374 disable_irq_wake(bf54x_kpad->irq); 385 disable_irq_wake(bf54x_kpad->irq);
375 386
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index ec96b369dd7a..05f3f43582c2 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -36,9 +36,10 @@ struct gpio_keys_drvdata {
36 struct gpio_button_data data[0]; 36 struct gpio_button_data data[0];
37}; 37};
38 38
39static void gpio_keys_report_event(struct gpio_keys_button *button, 39static void gpio_keys_report_event(struct gpio_button_data *bdata)
40 struct input_dev *input)
41{ 40{
41 struct gpio_keys_button *button = bdata->button;
42 struct input_dev *input = bdata->input;
42 unsigned int type = button->type ?: EV_KEY; 43 unsigned int type = button->type ?: EV_KEY;
43 int state = (gpio_get_value(button->gpio) ? 1 : 0) ^ button->active_low; 44 int state = (gpio_get_value(button->gpio) ? 1 : 0) ^ button->active_low;
44 45
@@ -50,34 +51,23 @@ static void gpio_check_button(unsigned long _data)
50{ 51{
51 struct gpio_button_data *data = (struct gpio_button_data *)_data; 52 struct gpio_button_data *data = (struct gpio_button_data *)_data;
52 53
53 gpio_keys_report_event(data->button, data->input); 54 gpio_keys_report_event(data);
54} 55}
55 56
56static irqreturn_t gpio_keys_isr(int irq, void *dev_id) 57static irqreturn_t gpio_keys_isr(int irq, void *dev_id)
57{ 58{
58 struct platform_device *pdev = dev_id; 59 struct gpio_button_data *bdata = dev_id;
59 struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; 60 struct gpio_keys_button *button = bdata->button;
60 struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev);
61 int i;
62 61
63 for (i = 0; i < pdata->nbuttons; i++) { 62 BUG_ON(irq != gpio_to_irq(button->gpio));
64 struct gpio_keys_button *button = &pdata->buttons[i];
65 63
66 if (irq == gpio_to_irq(button->gpio)) { 64 if (button->debounce_interval)
67 struct gpio_button_data *bdata = &ddata->data[i]; 65 mod_timer(&bdata->timer,
68 66 jiffies + msecs_to_jiffies(button->debounce_interval));
69 if (button->debounce_interval) 67 else
70 mod_timer(&bdata->timer, 68 gpio_keys_report_event(bdata);
71 jiffies +
72 msecs_to_jiffies(button->debounce_interval));
73 else
74 gpio_keys_report_event(button, bdata->input);
75
76 return IRQ_HANDLED;
77 }
78 }
79 69
80 return IRQ_NONE; 70 return IRQ_HANDLED;
81} 71}
82 72
83static int __devinit gpio_keys_probe(struct platform_device *pdev) 73static int __devinit gpio_keys_probe(struct platform_device *pdev)
@@ -151,7 +141,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
151 IRQF_SAMPLE_RANDOM | IRQF_TRIGGER_RISING | 141 IRQF_SAMPLE_RANDOM | IRQF_TRIGGER_RISING |
152 IRQF_TRIGGER_FALLING, 142 IRQF_TRIGGER_FALLING,
153 button->desc ? button->desc : "gpio_keys", 143 button->desc ? button->desc : "gpio_keys",
154 pdev); 144 bdata);
155 if (error) { 145 if (error) {
156 pr_err("gpio-keys: Unable to claim irq %d; error %d\n", 146 pr_err("gpio-keys: Unable to claim irq %d; error %d\n",
157 irq, error); 147 irq, error);
@@ -178,7 +168,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
178 168
179 fail2: 169 fail2:
180 while (--i >= 0) { 170 while (--i >= 0) {
181 free_irq(gpio_to_irq(pdata->buttons[i].gpio), pdev); 171 free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]);
182 if (pdata->buttons[i].debounce_interval) 172 if (pdata->buttons[i].debounce_interval)
183 del_timer_sync(&ddata->data[i].timer); 173 del_timer_sync(&ddata->data[i].timer);
184 gpio_free(pdata->buttons[i].gpio); 174 gpio_free(pdata->buttons[i].gpio);
@@ -203,7 +193,7 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev)
203 193
204 for (i = 0; i < pdata->nbuttons; i++) { 194 for (i = 0; i < pdata->nbuttons; i++) {
205 int irq = gpio_to_irq(pdata->buttons[i].gpio); 195 int irq = gpio_to_irq(pdata->buttons[i].gpio);
206 free_irq(irq, pdev); 196 free_irq(irq, &ddata->data[i]);
207 if (pdata->buttons[i].debounce_interval) 197 if (pdata->buttons[i].debounce_interval)
208 del_timer_sync(&ddata->data[i].timer); 198 del_timer_sync(&ddata->data[i].timer);
209 gpio_free(pdata->buttons[i].gpio); 199 gpio_free(pdata->buttons[i].gpio);
diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c
index dcea87a0bc56..69e674ecf19a 100644
--- a/drivers/input/keyboard/omap-keypad.c
+++ b/drivers/input/keyboard/omap-keypad.c
@@ -62,7 +62,7 @@ struct omap_kp {
62 unsigned int debounce; 62 unsigned int debounce;
63}; 63};
64 64
65DECLARE_TASKLET_DISABLED(kp_tasklet, omap_kp_tasklet, 0); 65static DECLARE_TASKLET_DISABLED(kp_tasklet, omap_kp_tasklet, 0);
66 66
67static int *keymap; 67static int *keymap;
68static unsigned int *row_gpios; 68static unsigned int *row_gpios;
@@ -72,12 +72,9 @@ static unsigned int *col_gpios;
72static void set_col_gpio_val(struct omap_kp *omap_kp, u8 value) 72static void set_col_gpio_val(struct omap_kp *omap_kp, u8 value)
73{ 73{
74 int col; 74 int col;
75 for (col = 0; col < omap_kp->cols; col++) { 75
76 if (value & (1 << col)) 76 for (col = 0; col < omap_kp->cols; col++)
77 omap_set_gpio_dataout(col_gpios[col], 1); 77 gpio_set_value(col_gpios[col], value & (1 << col));
78 else
79 omap_set_gpio_dataout(col_gpios[col], 0);
80 }
81} 78}
82 79
83static u8 get_row_gpio_val(struct omap_kp *omap_kp) 80static u8 get_row_gpio_val(struct omap_kp *omap_kp)
@@ -86,7 +83,7 @@ static u8 get_row_gpio_val(struct omap_kp *omap_kp)
86 u8 value = 0; 83 u8 value = 0;
87 84
88 for (row = 0; row < omap_kp->rows; row++) { 85 for (row = 0; row < omap_kp->rows; row++) {
89 if (omap_get_gpio_datain(row_gpios[row])) 86 if (gpio_get_value(row_gpios[row]))
90 value |= (1 << row); 87 value |= (1 << row);
91 } 88 }
92 return value; 89 return value;
@@ -333,23 +330,23 @@ static int __init omap_kp_probe(struct platform_device *pdev)
333 if (cpu_is_omap24xx()) { 330 if (cpu_is_omap24xx()) {
334 /* Cols: outputs */ 331 /* Cols: outputs */
335 for (col_idx = 0; col_idx < omap_kp->cols; col_idx++) { 332 for (col_idx = 0; col_idx < omap_kp->cols; col_idx++) {
336 if (omap_request_gpio(col_gpios[col_idx]) < 0) { 333 if (gpio_request(col_gpios[col_idx], "omap_kp_col") < 0) {
337 printk(KERN_ERR "Failed to request" 334 printk(KERN_ERR "Failed to request"
338 "GPIO%d for keypad\n", 335 "GPIO%d for keypad\n",
339 col_gpios[col_idx]); 336 col_gpios[col_idx]);
340 goto err1; 337 goto err1;
341 } 338 }
342 omap_set_gpio_direction(col_gpios[col_idx], 0); 339 gpio_direction_output(col_gpios[col_idx], 0);
343 } 340 }
344 /* Rows: inputs */ 341 /* Rows: inputs */
345 for (row_idx = 0; row_idx < omap_kp->rows; row_idx++) { 342 for (row_idx = 0; row_idx < omap_kp->rows; row_idx++) {
346 if (omap_request_gpio(row_gpios[row_idx]) < 0) { 343 if (gpio_request(row_gpios[row_idx], "omap_kp_row") < 0) {
347 printk(KERN_ERR "Failed to request" 344 printk(KERN_ERR "Failed to request"
348 "GPIO%d for keypad\n", 345 "GPIO%d for keypad\n",
349 row_gpios[row_idx]); 346 row_gpios[row_idx]);
350 goto err2; 347 goto err2;
351 } 348 }
352 omap_set_gpio_direction(row_gpios[row_idx], 1); 349 gpio_direction_input(row_gpios[row_idx]);
353 } 350 }
354 } else { 351 } else {
355 col_idx = 0; 352 col_idx = 0;
@@ -418,10 +415,10 @@ err3:
418 device_remove_file(&pdev->dev, &dev_attr_enable); 415 device_remove_file(&pdev->dev, &dev_attr_enable);
419err2: 416err2:
420 for (i = row_idx - 1; i >=0; i--) 417 for (i = row_idx - 1; i >=0; i--)
421 omap_free_gpio(row_gpios[i]); 418 gpio_free(row_gpios[i]);
422err1: 419err1:
423 for (i = col_idx - 1; i >=0; i--) 420 for (i = col_idx - 1; i >=0; i--)
424 omap_free_gpio(col_gpios[i]); 421 gpio_free(col_gpios[i]);
425 422
426 kfree(omap_kp); 423 kfree(omap_kp);
427 input_free_device(input_dev); 424 input_free_device(input_dev);
@@ -438,9 +435,9 @@ static int omap_kp_remove(struct platform_device *pdev)
438 if (cpu_is_omap24xx()) { 435 if (cpu_is_omap24xx()) {
439 int i; 436 int i;
440 for (i = 0; i < omap_kp->cols; i++) 437 for (i = 0; i < omap_kp->cols; i++)
441 omap_free_gpio(col_gpios[i]); 438 gpio_free(col_gpios[i]);
442 for (i = 0; i < omap_kp->rows; i++) { 439 for (i = 0; i < omap_kp->rows; i++) {
443 omap_free_gpio(row_gpios[i]); 440 gpio_free(row_gpios[i]);
444 free_irq(OMAP_GPIO_IRQ(row_gpios[i]), 0); 441 free_irq(OMAP_GPIO_IRQ(row_gpios[i]), 0);
445 } 442 }
446 } else { 443 } else {
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index e99b7882f382..199055db5082 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -180,6 +180,19 @@ config INPUT_YEALINK
180 To compile this driver as a module, choose M here: the module will be 180 To compile this driver as a module, choose M here: the module will be
181 called yealink. 181 called yealink.
182 182
183config INPUT_CM109
184 tristate "C-Media CM109 USB I/O Controller"
185 depends on EXPERIMENTAL
186 depends on USB_ARCH_HAS_HCD
187 select USB
188 help
189 Say Y here if you want to enable keyboard and buzzer functions of the
190 C-Media CM109 usb phones. The audio part is enabled by the generic
191 usb sound driver, so you might want to enable that as well.
192
193 To compile this driver as a module, choose M here: the module will be
194 called cm109.
195
183config INPUT_UINPUT 196config INPUT_UINPUT
184 tristate "User level driver support" 197 tristate "User level driver support"
185 help 198 help
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index f48009b52226..d7db2aeb8a98 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o
16obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o 16obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o
17obj-$(CONFIG_INPUT_POWERMATE) += powermate.o 17obj-$(CONFIG_INPUT_POWERMATE) += powermate.o
18obj-$(CONFIG_INPUT_YEALINK) += yealink.o 18obj-$(CONFIG_INPUT_YEALINK) += yealink.o
19obj-$(CONFIG_INPUT_CM109) += cm109.o
19obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o 20obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o
20obj-$(CONFIG_INPUT_UINPUT) += uinput.o 21obj-$(CONFIG_INPUT_UINPUT) += uinput.o
21obj-$(CONFIG_INPUT_APANEL) += apanel.o 22obj-$(CONFIG_INPUT_APANEL) += apanel.o
diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c
index a7fabafbd94c..3c9988dc0e9f 100644
--- a/drivers/input/misc/ati_remote2.c
+++ b/drivers/input/misc/ati_remote2.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * ati_remote2 - ATI/Philips USB RF remote driver 2 * ati_remote2 - ATI/Philips USB RF remote driver
3 * 3 *
4 * Copyright (C) 2005 Ville Syrjala <syrjala@sci.fi> 4 * Copyright (C) 2005-2008 Ville Syrjala <syrjala@sci.fi>
5 * Copyright (C) 2007 Peter Stokes <linux@dadeos.freeserve.co.uk> 5 * Copyright (C) 2007-2008 Peter Stokes <linux@dadeos.co.uk>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 8 * it under the terms of the GNU General Public License version 2
@@ -12,7 +12,7 @@
12#include <linux/usb/input.h> 12#include <linux/usb/input.h>
13 13
14#define DRIVER_DESC "ATI/Philips USB RF remote driver" 14#define DRIVER_DESC "ATI/Philips USB RF remote driver"
15#define DRIVER_VERSION "0.2" 15#define DRIVER_VERSION "0.3"
16 16
17MODULE_DESCRIPTION(DRIVER_DESC); 17MODULE_DESCRIPTION(DRIVER_DESC);
18MODULE_VERSION(DRIVER_VERSION); 18MODULE_VERSION(DRIVER_VERSION);
@@ -27,7 +27,7 @@ MODULE_LICENSE("GPL");
27 * A remote's "channel" may be altered by pressing and holding the "PC" button for 27 * A remote's "channel" may be altered by pressing and holding the "PC" button for
28 * approximately 3 seconds, after which the button will slowly flash the count of the 28 * approximately 3 seconds, after which the button will slowly flash the count of the
29 * currently configured "channel", using the numeric keypad enter a number between 1 and 29 * currently configured "channel", using the numeric keypad enter a number between 1 and
30 * 16 and then the "PC" button again, the button will slowly flash the count of the 30 * 16 and then press the "PC" button again, the button will slowly flash the count of the
31 * newly configured "channel". 31 * newly configured "channel".
32 */ 32 */
33 33
@@ -45,9 +45,25 @@ static struct usb_device_id ati_remote2_id_table[] = {
45}; 45};
46MODULE_DEVICE_TABLE(usb, ati_remote2_id_table); 46MODULE_DEVICE_TABLE(usb, ati_remote2_id_table);
47 47
48static struct { 48static DEFINE_MUTEX(ati_remote2_mutex);
49 int hw_code; 49
50 int key_code; 50enum {
51 ATI_REMOTE2_OPENED = 0x1,
52 ATI_REMOTE2_SUSPENDED = 0x2,
53};
54
55enum {
56 ATI_REMOTE2_AUX1,
57 ATI_REMOTE2_AUX2,
58 ATI_REMOTE2_AUX3,
59 ATI_REMOTE2_AUX4,
60 ATI_REMOTE2_PC,
61 ATI_REMOTE2_MODES,
62};
63
64static const struct {
65 u8 hw_code;
66 u16 keycode;
51} ati_remote2_key_table[] = { 67} ati_remote2_key_table[] = {
52 { 0x00, KEY_0 }, 68 { 0x00, KEY_0 },
53 { 0x01, KEY_1 }, 69 { 0x01, KEY_1 },
@@ -73,6 +89,7 @@ static struct {
73 { 0x37, KEY_RECORD }, 89 { 0x37, KEY_RECORD },
74 { 0x38, KEY_DVD }, 90 { 0x38, KEY_DVD },
75 { 0x39, KEY_TV }, 91 { 0x39, KEY_TV },
92 { 0x3f, KEY_PROG1 }, /* AUX1-AUX4 and PC */
76 { 0x54, KEY_MENU }, 93 { 0x54, KEY_MENU },
77 { 0x58, KEY_UP }, 94 { 0x58, KEY_UP },
78 { 0x59, KEY_DOWN }, 95 { 0x59, KEY_DOWN },
@@ -91,15 +108,9 @@ static struct {
91 { 0xa9, BTN_LEFT }, 108 { 0xa9, BTN_LEFT },
92 { 0xaa, BTN_RIGHT }, 109 { 0xaa, BTN_RIGHT },
93 { 0xbe, KEY_QUESTION }, 110 { 0xbe, KEY_QUESTION },
94 { 0xd5, KEY_FRONT },
95 { 0xd0, KEY_EDIT }, 111 { 0xd0, KEY_EDIT },
112 { 0xd5, KEY_FRONT },
96 { 0xf9, KEY_INFO }, 113 { 0xf9, KEY_INFO },
97 { (0x00 << 8) | 0x3f, KEY_PROG1 },
98 { (0x01 << 8) | 0x3f, KEY_PROG2 },
99 { (0x02 << 8) | 0x3f, KEY_PROG3 },
100 { (0x03 << 8) | 0x3f, KEY_PROG4 },
101 { (0x04 << 8) | 0x3f, KEY_PC },
102 { 0, KEY_RESERVED }
103}; 114};
104 115
105struct ati_remote2 { 116struct ati_remote2 {
@@ -117,46 +128,106 @@ struct ati_remote2 {
117 128
118 char name[64]; 129 char name[64];
119 char phys[64]; 130 char phys[64];
131
132 /* Each mode (AUX1-AUX4 and PC) can have an independent keymap. */
133 u16 keycode[ATI_REMOTE2_MODES][ARRAY_SIZE(ati_remote2_key_table)];
134
135 unsigned int flags;
120}; 136};
121 137
122static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id); 138static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id);
123static void ati_remote2_disconnect(struct usb_interface *interface); 139static void ati_remote2_disconnect(struct usb_interface *interface);
140static int ati_remote2_suspend(struct usb_interface *interface, pm_message_t message);
141static int ati_remote2_resume(struct usb_interface *interface);
124 142
125static struct usb_driver ati_remote2_driver = { 143static struct usb_driver ati_remote2_driver = {
126 .name = "ati_remote2", 144 .name = "ati_remote2",
127 .probe = ati_remote2_probe, 145 .probe = ati_remote2_probe,
128 .disconnect = ati_remote2_disconnect, 146 .disconnect = ati_remote2_disconnect,
129 .id_table = ati_remote2_id_table, 147 .id_table = ati_remote2_id_table,
148 .suspend = ati_remote2_suspend,
149 .resume = ati_remote2_resume,
150 .supports_autosuspend = 1,
130}; 151};
131 152
132static int ati_remote2_open(struct input_dev *idev) 153static int ati_remote2_submit_urbs(struct ati_remote2 *ar2)
133{ 154{
134 struct ati_remote2 *ar2 = input_get_drvdata(idev);
135 int r; 155 int r;
136 156
137 r = usb_submit_urb(ar2->urb[0], GFP_KERNEL); 157 r = usb_submit_urb(ar2->urb[0], GFP_KERNEL);
138 if (r) { 158 if (r) {
139 dev_err(&ar2->intf[0]->dev, 159 dev_err(&ar2->intf[0]->dev,
140 "%s: usb_submit_urb() = %d\n", __func__, r); 160 "%s(): usb_submit_urb() = %d\n", __func__, r);
141 return r; 161 return r;
142 } 162 }
143 r = usb_submit_urb(ar2->urb[1], GFP_KERNEL); 163 r = usb_submit_urb(ar2->urb[1], GFP_KERNEL);
144 if (r) { 164 if (r) {
145 usb_kill_urb(ar2->urb[0]); 165 usb_kill_urb(ar2->urb[0]);
146 dev_err(&ar2->intf[1]->dev, 166 dev_err(&ar2->intf[1]->dev,
147 "%s: usb_submit_urb() = %d\n", __func__, r); 167 "%s(): usb_submit_urb() = %d\n", __func__, r);
148 return r; 168 return r;
149 } 169 }
150 170
151 return 0; 171 return 0;
152} 172}
153 173
174static void ati_remote2_kill_urbs(struct ati_remote2 *ar2)
175{
176 usb_kill_urb(ar2->urb[1]);
177 usb_kill_urb(ar2->urb[0]);
178}
179
180static int ati_remote2_open(struct input_dev *idev)
181{
182 struct ati_remote2 *ar2 = input_get_drvdata(idev);
183 int r;
184
185 dev_dbg(&ar2->intf[0]->dev, "%s()\n", __func__);
186
187 r = usb_autopm_get_interface(ar2->intf[0]);
188 if (r) {
189 dev_err(&ar2->intf[0]->dev,
190 "%s(): usb_autopm_get_interface() = %d\n", __func__, r);
191 goto fail1;
192 }
193
194 mutex_lock(&ati_remote2_mutex);
195
196 if (!(ar2->flags & ATI_REMOTE2_SUSPENDED)) {
197 r = ati_remote2_submit_urbs(ar2);
198 if (r)
199 goto fail2;
200 }
201
202 ar2->flags |= ATI_REMOTE2_OPENED;
203
204 mutex_unlock(&ati_remote2_mutex);
205
206 usb_autopm_put_interface(ar2->intf[0]);
207
208 return 0;
209
210 fail2:
211 mutex_unlock(&ati_remote2_mutex);
212 usb_autopm_put_interface(ar2->intf[0]);
213 fail1:
214 return r;
215}
216
154static void ati_remote2_close(struct input_dev *idev) 217static void ati_remote2_close(struct input_dev *idev)
155{ 218{
156 struct ati_remote2 *ar2 = input_get_drvdata(idev); 219 struct ati_remote2 *ar2 = input_get_drvdata(idev);
157 220
158 usb_kill_urb(ar2->urb[0]); 221 dev_dbg(&ar2->intf[0]->dev, "%s()\n", __func__);
159 usb_kill_urb(ar2->urb[1]); 222
223 mutex_lock(&ati_remote2_mutex);
224
225 if (!(ar2->flags & ATI_REMOTE2_SUSPENDED))
226 ati_remote2_kill_urbs(ar2);
227
228 ar2->flags &= ~ATI_REMOTE2_OPENED;
229
230 mutex_unlock(&ati_remote2_mutex);
160} 231}
161 232
162static void ati_remote2_input_mouse(struct ati_remote2 *ar2) 233static void ati_remote2_input_mouse(struct ati_remote2 *ar2)
@@ -172,7 +243,7 @@ static void ati_remote2_input_mouse(struct ati_remote2 *ar2)
172 243
173 mode = data[0] & 0x0F; 244 mode = data[0] & 0x0F;
174 245
175 if (mode > 4) { 246 if (mode > ATI_REMOTE2_PC) {
176 dev_err(&ar2->intf[0]->dev, 247 dev_err(&ar2->intf[0]->dev,
177 "Unknown mode byte (%02x %02x %02x %02x)\n", 248 "Unknown mode byte (%02x %02x %02x %02x)\n",
178 data[3], data[2], data[1], data[0]); 249 data[3], data[2], data[1], data[0]);
@@ -191,7 +262,7 @@ static int ati_remote2_lookup(unsigned int hw_code)
191{ 262{
192 int i; 263 int i;
193 264
194 for (i = 0; ati_remote2_key_table[i].key_code != KEY_RESERVED; i++) 265 for (i = 0; i < ARRAY_SIZE(ati_remote2_key_table); i++)
195 if (ati_remote2_key_table[i].hw_code == hw_code) 266 if (ati_remote2_key_table[i].hw_code == hw_code)
196 return i; 267 return i;
197 268
@@ -211,7 +282,7 @@ static void ati_remote2_input_key(struct ati_remote2 *ar2)
211 282
212 mode = data[0] & 0x0F; 283 mode = data[0] & 0x0F;
213 284
214 if (mode > 4) { 285 if (mode > ATI_REMOTE2_PC) {
215 dev_err(&ar2->intf[1]->dev, 286 dev_err(&ar2->intf[1]->dev,
216 "Unknown mode byte (%02x %02x %02x %02x)\n", 287 "Unknown mode byte (%02x %02x %02x %02x)\n",
217 data[3], data[2], data[1], data[0]); 288 data[3], data[2], data[1], data[0]);
@@ -219,10 +290,6 @@ static void ati_remote2_input_key(struct ati_remote2 *ar2)
219 } 290 }
220 291
221 hw_code = data[2]; 292 hw_code = data[2];
222 /*
223 * Mode keys (AUX1-AUX4, PC) all generate the same code byte.
224 * Use the mode byte to figure out which one was pressed.
225 */
226 if (hw_code == 0x3f) { 293 if (hw_code == 0x3f) {
227 /* 294 /*
228 * For some incomprehensible reason the mouse pad generates 295 * For some incomprehensible reason the mouse pad generates
@@ -236,8 +303,6 @@ static void ati_remote2_input_key(struct ati_remote2 *ar2)
236 303
237 if (data[1] == 0) 304 if (data[1] == 0)
238 ar2->mode = mode; 305 ar2->mode = mode;
239
240 hw_code |= mode << 8;
241 } 306 }
242 307
243 if (!((1 << mode) & mode_mask)) 308 if (!((1 << mode) & mode_mask))
@@ -260,8 +325,8 @@ static void ati_remote2_input_key(struct ati_remote2 *ar2)
260 case 2: /* repeat */ 325 case 2: /* repeat */
261 326
262 /* No repeat for mouse buttons. */ 327 /* No repeat for mouse buttons. */
263 if (ati_remote2_key_table[index].key_code == BTN_LEFT || 328 if (ar2->keycode[mode][index] == BTN_LEFT ||
264 ati_remote2_key_table[index].key_code == BTN_RIGHT) 329 ar2->keycode[mode][index] == BTN_RIGHT)
265 return; 330 return;
266 331
267 if (!time_after_eq(jiffies, ar2->jiffies)) 332 if (!time_after_eq(jiffies, ar2->jiffies))
@@ -276,7 +341,7 @@ static void ati_remote2_input_key(struct ati_remote2 *ar2)
276 return; 341 return;
277 } 342 }
278 343
279 input_event(idev, EV_KEY, ati_remote2_key_table[index].key_code, data[1]); 344 input_event(idev, EV_KEY, ar2->keycode[mode][index], data[1]);
280 input_sync(idev); 345 input_sync(idev);
281} 346}
282 347
@@ -287,6 +352,7 @@ static void ati_remote2_complete_mouse(struct urb *urb)
287 352
288 switch (urb->status) { 353 switch (urb->status) {
289 case 0: 354 case 0:
355 usb_mark_last_busy(ar2->udev);
290 ati_remote2_input_mouse(ar2); 356 ati_remote2_input_mouse(ar2);
291 break; 357 break;
292 case -ENOENT: 358 case -ENOENT:
@@ -297,6 +363,7 @@ static void ati_remote2_complete_mouse(struct urb *urb)
297 "%s(): urb status = %d\n", __func__, urb->status); 363 "%s(): urb status = %d\n", __func__, urb->status);
298 return; 364 return;
299 default: 365 default:
366 usb_mark_last_busy(ar2->udev);
300 dev_err(&ar2->intf[0]->dev, 367 dev_err(&ar2->intf[0]->dev,
301 "%s(): urb status = %d\n", __func__, urb->status); 368 "%s(): urb status = %d\n", __func__, urb->status);
302 } 369 }
@@ -314,6 +381,7 @@ static void ati_remote2_complete_key(struct urb *urb)
314 381
315 switch (urb->status) { 382 switch (urb->status) {
316 case 0: 383 case 0:
384 usb_mark_last_busy(ar2->udev);
317 ati_remote2_input_key(ar2); 385 ati_remote2_input_key(ar2);
318 break; 386 break;
319 case -ENOENT: 387 case -ENOENT:
@@ -324,6 +392,7 @@ static void ati_remote2_complete_key(struct urb *urb)
324 "%s(): urb status = %d\n", __func__, urb->status); 392 "%s(): urb status = %d\n", __func__, urb->status);
325 return; 393 return;
326 default: 394 default:
395 usb_mark_last_busy(ar2->udev);
327 dev_err(&ar2->intf[1]->dev, 396 dev_err(&ar2->intf[1]->dev,
328 "%s(): urb status = %d\n", __func__, urb->status); 397 "%s(): urb status = %d\n", __func__, urb->status);
329 } 398 }
@@ -334,10 +403,60 @@ static void ati_remote2_complete_key(struct urb *urb)
334 "%s(): usb_submit_urb() = %d\n", __func__, r); 403 "%s(): usb_submit_urb() = %d\n", __func__, r);
335} 404}
336 405
406static int ati_remote2_getkeycode(struct input_dev *idev,
407 int scancode, int *keycode)
408{
409 struct ati_remote2 *ar2 = input_get_drvdata(idev);
410 int index, mode;
411
412 mode = scancode >> 8;
413 if (mode > ATI_REMOTE2_PC || !((1 << mode) & mode_mask))
414 return -EINVAL;
415
416 index = ati_remote2_lookup(scancode & 0xFF);
417 if (index < 0)
418 return -EINVAL;
419
420 *keycode = ar2->keycode[mode][index];
421 return 0;
422}
423
424static int ati_remote2_setkeycode(struct input_dev *idev, int scancode, int keycode)
425{
426 struct ati_remote2 *ar2 = input_get_drvdata(idev);
427 int index, mode, old_keycode;
428
429 mode = scancode >> 8;
430 if (mode > ATI_REMOTE2_PC || !((1 << mode) & mode_mask))
431 return -EINVAL;
432
433 index = ati_remote2_lookup(scancode & 0xFF);
434 if (index < 0)
435 return -EINVAL;
436
437 if (keycode < KEY_RESERVED || keycode > KEY_MAX)
438 return -EINVAL;
439
440 old_keycode = ar2->keycode[mode][index];
441 ar2->keycode[mode][index] = keycode;
442 set_bit(keycode, idev->keybit);
443
444 for (mode = 0; mode < ATI_REMOTE2_MODES; mode++) {
445 for (index = 0; index < ARRAY_SIZE(ati_remote2_key_table); index++) {
446 if (ar2->keycode[mode][index] == old_keycode)
447 return 0;
448 }
449 }
450
451 clear_bit(old_keycode, idev->keybit);
452
453 return 0;
454}
455
337static int ati_remote2_input_init(struct ati_remote2 *ar2) 456static int ati_remote2_input_init(struct ati_remote2 *ar2)
338{ 457{
339 struct input_dev *idev; 458 struct input_dev *idev;
340 int i, retval; 459 int index, mode, retval;
341 460
342 idev = input_allocate_device(); 461 idev = input_allocate_device();
343 if (!idev) 462 if (!idev)
@@ -350,8 +469,26 @@ static int ati_remote2_input_init(struct ati_remote2 *ar2)
350 idev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | 469 idev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
351 BIT_MASK(BTN_RIGHT); 470 BIT_MASK(BTN_RIGHT);
352 idev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); 471 idev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
353 for (i = 0; ati_remote2_key_table[i].key_code != KEY_RESERVED; i++) 472
354 set_bit(ati_remote2_key_table[i].key_code, idev->keybit); 473 for (mode = 0; mode < ATI_REMOTE2_MODES; mode++) {
474 for (index = 0; index < ARRAY_SIZE(ati_remote2_key_table); index++) {
475 ar2->keycode[mode][index] = ati_remote2_key_table[index].keycode;
476 set_bit(ar2->keycode[mode][index], idev->keybit);
477 }
478 }
479
480 /* AUX1-AUX4 and PC generate the same scancode. */
481 index = ati_remote2_lookup(0x3f);
482 ar2->keycode[ATI_REMOTE2_AUX1][index] = KEY_PROG1;
483 ar2->keycode[ATI_REMOTE2_AUX2][index] = KEY_PROG2;
484 ar2->keycode[ATI_REMOTE2_AUX3][index] = KEY_PROG3;
485 ar2->keycode[ATI_REMOTE2_AUX4][index] = KEY_PROG4;
486 ar2->keycode[ATI_REMOTE2_PC][index] = KEY_PC;
487 set_bit(KEY_PROG1, idev->keybit);
488 set_bit(KEY_PROG2, idev->keybit);
489 set_bit(KEY_PROG3, idev->keybit);
490 set_bit(KEY_PROG4, idev->keybit);
491 set_bit(KEY_PC, idev->keybit);
355 492
356 idev->rep[REP_DELAY] = 250; 493 idev->rep[REP_DELAY] = 250;
357 idev->rep[REP_PERIOD] = 33; 494 idev->rep[REP_PERIOD] = 33;
@@ -359,6 +496,9 @@ static int ati_remote2_input_init(struct ati_remote2 *ar2)
359 idev->open = ati_remote2_open; 496 idev->open = ati_remote2_open;
360 idev->close = ati_remote2_close; 497 idev->close = ati_remote2_close;
361 498
499 idev->getkeycode = ati_remote2_getkeycode;
500 idev->setkeycode = ati_remote2_setkeycode;
501
362 idev->name = ar2->name; 502 idev->name = ar2->name;
363 idev->phys = ar2->phys; 503 idev->phys = ar2->phys;
364 504
@@ -490,6 +630,8 @@ static int ati_remote2_probe(struct usb_interface *interface, const struct usb_d
490 630
491 usb_set_intfdata(interface, ar2); 631 usb_set_intfdata(interface, ar2);
492 632
633 interface->needs_remote_wakeup = 1;
634
493 return 0; 635 return 0;
494 636
495 fail2: 637 fail2:
@@ -522,6 +664,57 @@ static void ati_remote2_disconnect(struct usb_interface *interface)
522 kfree(ar2); 664 kfree(ar2);
523} 665}
524 666
667static int ati_remote2_suspend(struct usb_interface *interface,
668 pm_message_t message)
669{
670 struct ati_remote2 *ar2;
671 struct usb_host_interface *alt = interface->cur_altsetting;
672
673 if (alt->desc.bInterfaceNumber)
674 return 0;
675
676 ar2 = usb_get_intfdata(interface);
677
678 dev_dbg(&ar2->intf[0]->dev, "%s()\n", __func__);
679
680 mutex_lock(&ati_remote2_mutex);
681
682 if (ar2->flags & ATI_REMOTE2_OPENED)
683 ati_remote2_kill_urbs(ar2);
684
685 ar2->flags |= ATI_REMOTE2_SUSPENDED;
686
687 mutex_unlock(&ati_remote2_mutex);
688
689 return 0;
690}
691
692static int ati_remote2_resume(struct usb_interface *interface)
693{
694 struct ati_remote2 *ar2;
695 struct usb_host_interface *alt = interface->cur_altsetting;
696 int r = 0;
697
698 if (alt->desc.bInterfaceNumber)
699 return 0;
700
701 ar2 = usb_get_intfdata(interface);
702
703 dev_dbg(&ar2->intf[0]->dev, "%s()\n", __func__);
704
705 mutex_lock(&ati_remote2_mutex);
706
707 if (ar2->flags & ATI_REMOTE2_OPENED)
708 r = ati_remote2_submit_urbs(ar2);
709
710 if (!r)
711 ar2->flags &= ~ATI_REMOTE2_SUSPENDED;
712
713 mutex_unlock(&ati_remote2_mutex);
714
715 return r;
716}
717
525static int __init ati_remote2_init(void) 718static int __init ati_remote2_init(void)
526{ 719{
527 int r; 720 int r;
diff --git a/drivers/input/misc/cm109.c b/drivers/input/misc/cm109.c
new file mode 100644
index 000000000000..bce160f4349b
--- /dev/null
+++ b/drivers/input/misc/cm109.c
@@ -0,0 +1,882 @@
1/*
2 * Driver for the VoIP USB phones with CM109 chipsets.
3 *
4 * Copyright (C) 2007 - 2008 Alfred E. Heggestad <aeh@db.org>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 */
10
11/*
12 * Tested devices:
13 * - Komunikate KIP1000
14 * - Genius G-talk
15 * - Allied-Telesis Corega USBPH01
16 * - ...
17 *
18 * This driver is based on the yealink.c driver
19 *
20 * Thanks to:
21 * - Authors of yealink.c
22 * - Thomas Reitmayr
23 * - Oliver Neukum for good review comments and code
24 * - Shaun Jackman <sjackman@gmail.com> for Genius G-talk keymap
25 * - Dmitry Torokhov for valuable input and review
26 *
27 * Todo:
28 * - Read/write EEPROM
29 */
30
31#include <linux/kernel.h>
32#include <linux/init.h>
33#include <linux/slab.h>
34#include <linux/module.h>
35#include <linux/moduleparam.h>
36#include <linux/rwsem.h>
37#include <linux/usb/input.h>
38
39#define DRIVER_VERSION "20080805"
40#define DRIVER_AUTHOR "Alfred E. Heggestad"
41#define DRIVER_DESC "CM109 phone driver"
42
43static char *phone = "kip1000";
44module_param(phone, charp, S_IRUSR);
45MODULE_PARM_DESC(phone, "Phone name {kip1000, gtalk, usbph01}");
46
47enum {
48 /* HID Registers */
49 HID_IR0 = 0x00, /* Record/Playback-mute button, Volume up/down */
50 HID_IR1 = 0x01, /* GPI, generic registers or EEPROM_DATA0 */
51 HID_IR2 = 0x02, /* Generic registers or EEPROM_DATA1 */
52 HID_IR3 = 0x03, /* Generic registers or EEPROM_CTRL */
53 HID_OR0 = 0x00, /* Mapping control, buzzer, SPDIF (offset 0x04) */
54 HID_OR1 = 0x01, /* GPO - General Purpose Output */
55 HID_OR2 = 0x02, /* Set GPIO to input/output mode */
56 HID_OR3 = 0x03, /* SPDIF status channel or EEPROM_CTRL */
57
58 /* HID_IR0 */
59 RECORD_MUTE = 1 << 3,
60 PLAYBACK_MUTE = 1 << 2,
61 VOLUME_DOWN = 1 << 1,
62 VOLUME_UP = 1 << 0,
63
64 /* HID_OR0 */
65 /* bits 7-6
66 0: HID_OR1-2 are used for GPO; HID_OR0, 3 are used for buzzer
67 and SPDIF
68 1: HID_OR0-3 are used as generic HID registers
69 2: Values written to HID_OR0-3 are also mapped to MCU_CTRL,
70 EEPROM_DATA0-1, EEPROM_CTRL (see Note)
71 3: Reserved
72 */
73 HID_OR_GPO_BUZ_SPDIF = 0 << 6,
74 HID_OR_GENERIC_HID_REG = 1 << 6,
75 HID_OR_MAP_MCU_EEPROM = 2 << 6,
76
77 BUZZER_ON = 1 << 5,
78
79 /* up to 256 normal keys, up to 16 special keys */
80 KEYMAP_SIZE = 256 + 16,
81};
82
83/* CM109 protocol packet */
84struct cm109_ctl_packet {
85 u8 byte[4];
86} __attribute__ ((packed));
87
88enum { USB_PKT_LEN = sizeof(struct cm109_ctl_packet) };
89
90/* CM109 device structure */
91struct cm109_dev {
92 struct input_dev *idev; /* input device */
93 struct usb_device *udev; /* usb device */
94 struct usb_interface *intf;
95
96 /* irq input channel */
97 struct cm109_ctl_packet *irq_data;
98 dma_addr_t irq_dma;
99 struct urb *urb_irq;
100
101 /* control output channel */
102 struct cm109_ctl_packet *ctl_data;
103 dma_addr_t ctl_dma;
104 struct usb_ctrlrequest *ctl_req;
105 dma_addr_t ctl_req_dma;
106 struct urb *urb_ctl;
107 /*
108 * The 3 bitfields below are protected by ctl_submit_lock.
109 * They have to be separate since they are accessed from IRQ
110 * context.
111 */
112 unsigned irq_urb_pending:1; /* irq_urb is in flight */
113 unsigned ctl_urb_pending:1; /* ctl_urb is in flight */
114 unsigned buzzer_pending:1; /* need to issue buzz command */
115 spinlock_t ctl_submit_lock;
116
117 unsigned char buzzer_state; /* on/off */
118
119 /* flags */
120 unsigned open:1;
121 unsigned resetting:1;
122 unsigned shutdown:1;
123
124 /* This mutex protects writes to the above flags */
125 struct mutex pm_mutex;
126
127 unsigned short keymap[KEYMAP_SIZE];
128
129 char phys[64]; /* physical device path */
130 int key_code; /* last reported key */
131 int keybit; /* 0=new scan 1,2,4,8=scan columns */
132 u8 gpi; /* Cached value of GPI (high nibble) */
133};
134
135/******************************************************************************
136 * CM109 key interface
137 *****************************************************************************/
138
139static unsigned short special_keymap(int code)
140{
141 if (code > 0xff) {
142 switch (code - 0xff) {
143 case RECORD_MUTE: return KEY_MUTE;
144 case PLAYBACK_MUTE: return KEY_MUTE;
145 case VOLUME_DOWN: return KEY_VOLUMEDOWN;
146 case VOLUME_UP: return KEY_VOLUMEUP;
147 }
148 }
149 return KEY_RESERVED;
150}
151
152/* Map device buttons to internal key events.
153 *
154 * The "up" and "down" keys, are symbolised by arrows on the button.
155 * The "pickup" and "hangup" keys are symbolised by a green and red phone
156 * on the button.
157
158 Komunikate KIP1000 Keyboard Matrix
159
160 -> -- 1 -- 2 -- 3 --> GPI pin 4 (0x10)
161 | | | |
162 <- -- 4 -- 5 -- 6 --> GPI pin 5 (0x20)
163 | | | |
164 END - 7 -- 8 -- 9 --> GPI pin 6 (0x40)
165 | | | |
166 OK -- * -- 0 -- # --> GPI pin 7 (0x80)
167 | | | |
168
169 /|\ /|\ /|\ /|\
170 | | | |
171GPO
172pin: 3 2 1 0
173 0x8 0x4 0x2 0x1
174
175 */
176static unsigned short keymap_kip1000(int scancode)
177{
178 switch (scancode) { /* phone key: */
179 case 0x82: return KEY_NUMERIC_0; /* 0 */
180 case 0x14: return KEY_NUMERIC_1; /* 1 */
181 case 0x12: return KEY_NUMERIC_2; /* 2 */
182 case 0x11: return KEY_NUMERIC_3; /* 3 */
183 case 0x24: return KEY_NUMERIC_4; /* 4 */
184 case 0x22: return KEY_NUMERIC_5; /* 5 */
185 case 0x21: return KEY_NUMERIC_6; /* 6 */
186 case 0x44: return KEY_NUMERIC_7; /* 7 */
187 case 0x42: return KEY_NUMERIC_8; /* 8 */
188 case 0x41: return KEY_NUMERIC_9; /* 9 */
189 case 0x81: return KEY_NUMERIC_POUND; /* # */
190 case 0x84: return KEY_NUMERIC_STAR; /* * */
191 case 0x88: return KEY_ENTER; /* pickup */
192 case 0x48: return KEY_ESC; /* hangup */
193 case 0x28: return KEY_LEFT; /* IN */
194 case 0x18: return KEY_RIGHT; /* OUT */
195 default: return special_keymap(scancode);
196 }
197}
198
199/*
200 Contributed by Shaun Jackman <sjackman@gmail.com>
201
202 Genius G-Talk keyboard matrix
203 0 1 2 3
204 4: 0 4 8 Talk
205 5: 1 5 9 End
206 6: 2 6 # Up
207 7: 3 7 * Down
208*/
209static unsigned short keymap_gtalk(int scancode)
210{
211 switch (scancode) {
212 case 0x11: return KEY_NUMERIC_0;
213 case 0x21: return KEY_NUMERIC_1;
214 case 0x41: return KEY_NUMERIC_2;
215 case 0x81: return KEY_NUMERIC_3;
216 case 0x12: return KEY_NUMERIC_4;
217 case 0x22: return KEY_NUMERIC_5;
218 case 0x42: return KEY_NUMERIC_6;
219 case 0x82: return KEY_NUMERIC_7;
220 case 0x14: return KEY_NUMERIC_8;
221 case 0x24: return KEY_NUMERIC_9;
222 case 0x44: return KEY_NUMERIC_POUND; /* # */
223 case 0x84: return KEY_NUMERIC_STAR; /* * */
224 case 0x18: return KEY_ENTER; /* Talk (green handset) */
225 case 0x28: return KEY_ESC; /* End (red handset) */
226 case 0x48: return KEY_UP; /* Menu up (rocker switch) */
227 case 0x88: return KEY_DOWN; /* Menu down (rocker switch) */
228 default: return special_keymap(scancode);
229 }
230}
231
232/*
233 * Keymap for Allied-Telesis Corega USBPH01
234 * http://www.alliedtelesis-corega.com/2/1344/1437/1360/chprd.html
235 *
236 * Contributed by july@nat.bg
237 */
238static unsigned short keymap_usbph01(int scancode)
239{
240 switch (scancode) {
241 case 0x11: return KEY_NUMERIC_0; /* 0 */
242 case 0x21: return KEY_NUMERIC_1; /* 1 */
243 case 0x41: return KEY_NUMERIC_2; /* 2 */
244 case 0x81: return KEY_NUMERIC_3; /* 3 */
245 case 0x12: return KEY_NUMERIC_4; /* 4 */
246 case 0x22: return KEY_NUMERIC_5; /* 5 */
247 case 0x42: return KEY_NUMERIC_6; /* 6 */
248 case 0x82: return KEY_NUMERIC_7; /* 7 */
249 case 0x14: return KEY_NUMERIC_8; /* 8 */
250 case 0x24: return KEY_NUMERIC_9; /* 9 */
251 case 0x44: return KEY_NUMERIC_POUND; /* # */
252 case 0x84: return KEY_NUMERIC_STAR; /* * */
253 case 0x18: return KEY_ENTER; /* pickup */
254 case 0x28: return KEY_ESC; /* hangup */
255 case 0x48: return KEY_LEFT; /* IN */
256 case 0x88: return KEY_RIGHT; /* OUT */
257 default: return special_keymap(scancode);
258 }
259}
260
261static unsigned short (*keymap)(int) = keymap_kip1000;
262
263/*
264 * Completes a request by converting the data into events for the
265 * input subsystem.
266 */
267static void report_key(struct cm109_dev *dev, int key)
268{
269 struct input_dev *idev = dev->idev;
270
271 if (dev->key_code >= 0) {
272 /* old key up */
273 input_report_key(idev, dev->key_code, 0);
274 }
275
276 dev->key_code = key;
277 if (key >= 0) {
278 /* new valid key */
279 input_report_key(idev, key, 1);
280 }
281
282 input_sync(idev);
283}
284
285/******************************************************************************
286 * CM109 usb communication interface
287 *****************************************************************************/
288
289static void cm109_submit_buzz_toggle(struct cm109_dev *dev)
290{
291 int error;
292
293 if (dev->buzzer_state)
294 dev->ctl_data->byte[HID_OR0] |= BUZZER_ON;
295 else
296 dev->ctl_data->byte[HID_OR0] &= ~BUZZER_ON;
297
298 error = usb_submit_urb(dev->urb_ctl, GFP_ATOMIC);
299 if (error)
300 err("%s: usb_submit_urb (urb_ctl) failed %d", __func__, error);
301}
302
303/*
304 * IRQ handler
305 */
306static void cm109_urb_irq_callback(struct urb *urb)
307{
308 struct cm109_dev *dev = urb->context;
309 const int status = urb->status;
310 int error;
311
312 dev_dbg(&urb->dev->dev, "### URB IRQ: [0x%02x 0x%02x 0x%02x 0x%02x] keybit=0x%02x\n",
313 dev->irq_data->byte[0],
314 dev->irq_data->byte[1],
315 dev->irq_data->byte[2],
316 dev->irq_data->byte[3],
317 dev->keybit);
318
319 if (status) {
320 if (status == -ESHUTDOWN)
321 return;
322 err("%s: urb status %d", __func__, status);
323 }
324
325 /* Special keys */
326 if (dev->irq_data->byte[HID_IR0] & 0x0f) {
327 const int code = (dev->irq_data->byte[HID_IR0] & 0x0f);
328 report_key(dev, dev->keymap[0xff + code]);
329 }
330
331 /* Scan key column */
332 if (dev->keybit == 0xf) {
333
334 /* Any changes ? */
335 if ((dev->gpi & 0xf0) == (dev->irq_data->byte[HID_IR1] & 0xf0))
336 goto out;
337
338 dev->gpi = dev->irq_data->byte[HID_IR1] & 0xf0;
339 dev->keybit = 0x1;
340 } else {
341 report_key(dev, dev->keymap[dev->irq_data->byte[HID_IR1]]);
342
343 dev->keybit <<= 1;
344 if (dev->keybit > 0x8)
345 dev->keybit = 0xf;
346 }
347
348 out:
349
350 spin_lock(&dev->ctl_submit_lock);
351
352 dev->irq_urb_pending = 0;
353
354 if (likely(!dev->shutdown)) {
355
356 if (dev->buzzer_state)
357 dev->ctl_data->byte[HID_OR0] |= BUZZER_ON;
358 else
359 dev->ctl_data->byte[HID_OR0] &= ~BUZZER_ON;
360
361 dev->ctl_data->byte[HID_OR1] = dev->keybit;
362 dev->ctl_data->byte[HID_OR2] = dev->keybit;
363
364 dev->buzzer_pending = 0;
365 dev->ctl_urb_pending = 1;
366
367 error = usb_submit_urb(dev->urb_ctl, GFP_ATOMIC);
368 if (error)
369 err("%s: usb_submit_urb (urb_ctl) failed %d",
370 __func__, error);
371 }
372
373 spin_unlock(&dev->ctl_submit_lock);
374}
375
376static void cm109_urb_ctl_callback(struct urb *urb)
377{
378 struct cm109_dev *dev = urb->context;
379 const int status = urb->status;
380 int error;
381
382 dev_dbg(&urb->dev->dev, "### URB CTL: [0x%02x 0x%02x 0x%02x 0x%02x]\n",
383 dev->ctl_data->byte[0],
384 dev->ctl_data->byte[1],
385 dev->ctl_data->byte[2],
386 dev->ctl_data->byte[3]);
387
388 if (status)
389 err("%s: urb status %d", __func__, status);
390
391 spin_lock(&dev->ctl_submit_lock);
392
393 dev->ctl_urb_pending = 0;
394
395 if (likely(!dev->shutdown)) {
396
397 if (dev->buzzer_pending) {
398 dev->buzzer_pending = 0;
399 dev->ctl_urb_pending = 1;
400 cm109_submit_buzz_toggle(dev);
401 } else if (likely(!dev->irq_urb_pending)) {
402 /* ask for key data */
403 dev->irq_urb_pending = 1;
404 error = usb_submit_urb(dev->urb_irq, GFP_ATOMIC);
405 if (error)
406 err("%s: usb_submit_urb (urb_irq) failed %d",
407 __func__, error);
408 }
409 }
410
411 spin_unlock(&dev->ctl_submit_lock);
412}
413
414static void cm109_toggle_buzzer_async(struct cm109_dev *dev)
415{
416 unsigned long flags;
417
418 spin_lock_irqsave(&dev->ctl_submit_lock, flags);
419
420 if (dev->ctl_urb_pending) {
421 /* URB completion will resubmit */
422 dev->buzzer_pending = 1;
423 } else {
424 dev->ctl_urb_pending = 1;
425 cm109_submit_buzz_toggle(dev);
426 }
427
428 spin_unlock_irqrestore(&dev->ctl_submit_lock, flags);
429}
430
431static void cm109_toggle_buzzer_sync(struct cm109_dev *dev, int on)
432{
433 int error;
434
435 if (on)
436 dev->ctl_data->byte[HID_OR0] |= BUZZER_ON;
437 else
438 dev->ctl_data->byte[HID_OR0] &= ~BUZZER_ON;
439
440 error = usb_control_msg(dev->udev,
441 usb_sndctrlpipe(dev->udev, 0),
442 dev->ctl_req->bRequest,
443 dev->ctl_req->bRequestType,
444 le16_to_cpu(dev->ctl_req->wValue),
445 le16_to_cpu(dev->ctl_req->wIndex),
446 dev->ctl_data,
447 USB_PKT_LEN, USB_CTRL_SET_TIMEOUT);
448 if (error && error != EINTR)
449 err("%s: usb_control_msg() failed %d", __func__, error);
450}
451
452static void cm109_stop_traffic(struct cm109_dev *dev)
453{
454 dev->shutdown = 1;
455 /*
456 * Make sure other CPUs see this
457 */
458 smp_wmb();
459
460 usb_kill_urb(dev->urb_ctl);
461 usb_kill_urb(dev->urb_irq);
462
463 cm109_toggle_buzzer_sync(dev, 0);
464
465 dev->shutdown = 0;
466 smp_wmb();
467}
468
469static void cm109_restore_state(struct cm109_dev *dev)
470{
471 if (dev->open) {
472 /*
473 * Restore buzzer state.
474 * This will also kick regular URB submission
475 */
476 cm109_toggle_buzzer_async(dev);
477 }
478}
479
480/******************************************************************************
481 * input event interface
482 *****************************************************************************/
483
484static int cm109_input_open(struct input_dev *idev)
485{
486 struct cm109_dev *dev = input_get_drvdata(idev);
487 int error;
488
489 error = usb_autopm_get_interface(dev->intf);
490 if (error < 0) {
491 err("%s - cannot autoresume, result %d",
492 __func__, error);
493 return error;
494 }
495
496 mutex_lock(&dev->pm_mutex);
497
498 dev->buzzer_state = 0;
499 dev->key_code = -1; /* no keys pressed */
500 dev->keybit = 0xf;
501
502 /* issue INIT */
503 dev->ctl_data->byte[HID_OR0] = HID_OR_GPO_BUZ_SPDIF;
504 dev->ctl_data->byte[HID_OR1] = dev->keybit;
505 dev->ctl_data->byte[HID_OR2] = dev->keybit;
506 dev->ctl_data->byte[HID_OR3] = 0x00;
507
508 error = usb_submit_urb(dev->urb_ctl, GFP_KERNEL);
509 if (error)
510 err("%s: usb_submit_urb (urb_ctl) failed %d", __func__, error);
511 else
512 dev->open = 1;
513
514 mutex_unlock(&dev->pm_mutex);
515
516 if (error)
517 usb_autopm_put_interface(dev->intf);
518
519 return error;
520}
521
522static void cm109_input_close(struct input_dev *idev)
523{
524 struct cm109_dev *dev = input_get_drvdata(idev);
525
526 mutex_lock(&dev->pm_mutex);
527
528 /*
529 * Once we are here event delivery is stopped so we
530 * don't need to worry about someone starting buzzer
531 * again
532 */
533 cm109_stop_traffic(dev);
534 dev->open = 0;
535
536 mutex_unlock(&dev->pm_mutex);
537
538 usb_autopm_put_interface(dev->intf);
539}
540
541static int cm109_input_ev(struct input_dev *idev, unsigned int type,
542 unsigned int code, int value)
543{
544 struct cm109_dev *dev = input_get_drvdata(idev);
545
546 dev_dbg(&dev->udev->dev,
547 "input_ev: type=%u code=%u value=%d\n", type, code, value);
548
549 if (type != EV_SND)
550 return -EINVAL;
551
552 switch (code) {
553 case SND_TONE:
554 case SND_BELL:
555 dev->buzzer_state = !!value;
556 if (!dev->resetting)
557 cm109_toggle_buzzer_async(dev);
558 return 0;
559
560 default:
561 return -EINVAL;
562 }
563}
564
565
566/******************************************************************************
567 * Linux interface and usb initialisation
568 *****************************************************************************/
569
570struct driver_info {
571 char *name;
572};
573
574static const struct driver_info info_cm109 = {
575 .name = "CM109 USB driver",
576};
577
578enum {
579 VENDOR_ID = 0x0d8c, /* C-Media Electronics */
580 PRODUCT_ID_CM109 = 0x000e, /* CM109 defines range 0x0008 - 0x000f */
581};
582
583/* table of devices that work with this driver */
584static const struct usb_device_id cm109_usb_table[] = {
585 {
586 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
587 USB_DEVICE_ID_MATCH_INT_INFO,
588 .idVendor = VENDOR_ID,
589 .idProduct = PRODUCT_ID_CM109,
590 .bInterfaceClass = USB_CLASS_HID,
591 .bInterfaceSubClass = 0,
592 .bInterfaceProtocol = 0,
593 .driver_info = (kernel_ulong_t) &info_cm109
594 },
595 /* you can add more devices here with product ID 0x0008 - 0x000f */
596 { }
597};
598
599static void cm109_usb_cleanup(struct cm109_dev *dev)
600{
601 if (dev->ctl_req)
602 usb_buffer_free(dev->udev, sizeof(*(dev->ctl_req)),
603 dev->ctl_req, dev->ctl_req_dma);
604 if (dev->ctl_data)
605 usb_buffer_free(dev->udev, USB_PKT_LEN,
606 dev->ctl_data, dev->ctl_dma);
607 if (dev->irq_data)
608 usb_buffer_free(dev->udev, USB_PKT_LEN,
609 dev->irq_data, dev->irq_dma);
610
611 usb_free_urb(dev->urb_irq); /* parameter validation in core/urb */
612 usb_free_urb(dev->urb_ctl); /* parameter validation in core/urb */
613 kfree(dev);
614}
615
616static void cm109_usb_disconnect(struct usb_interface *interface)
617{
618 struct cm109_dev *dev = usb_get_intfdata(interface);
619
620 usb_set_intfdata(interface, NULL);
621 input_unregister_device(dev->idev);
622 cm109_usb_cleanup(dev);
623}
624
625static int cm109_usb_probe(struct usb_interface *intf,
626 const struct usb_device_id *id)
627{
628 struct usb_device *udev = interface_to_usbdev(intf);
629 struct driver_info *nfo = (struct driver_info *)id->driver_info;
630 struct usb_host_interface *interface;
631 struct usb_endpoint_descriptor *endpoint;
632 struct cm109_dev *dev;
633 struct input_dev *input_dev = NULL;
634 int ret, pipe, i;
635 int error = -ENOMEM;
636
637 interface = intf->cur_altsetting;
638 endpoint = &interface->endpoint[0].desc;
639
640 if (!usb_endpoint_is_int_in(endpoint))
641 return -ENODEV;
642
643 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
644 if (!dev)
645 return -ENOMEM;
646
647 spin_lock_init(&dev->ctl_submit_lock);
648 mutex_init(&dev->pm_mutex);
649
650 dev->udev = udev;
651 dev->intf = intf;
652
653 dev->idev = input_dev = input_allocate_device();
654 if (!input_dev)
655 goto err_out;
656
657 /* allocate usb buffers */
658 dev->irq_data = usb_buffer_alloc(udev, USB_PKT_LEN,
659 GFP_KERNEL, &dev->irq_dma);
660 if (!dev->irq_data)
661 goto err_out;
662
663 dev->ctl_data = usb_buffer_alloc(udev, USB_PKT_LEN,
664 GFP_KERNEL, &dev->ctl_dma);
665 if (!dev->ctl_data)
666 goto err_out;
667
668 dev->ctl_req = usb_buffer_alloc(udev, sizeof(*(dev->ctl_req)),
669 GFP_KERNEL, &dev->ctl_req_dma);
670 if (!dev->ctl_req)
671 goto err_out;
672
673 /* allocate urb structures */
674 dev->urb_irq = usb_alloc_urb(0, GFP_KERNEL);
675 if (!dev->urb_irq)
676 goto err_out;
677
678 dev->urb_ctl = usb_alloc_urb(0, GFP_KERNEL);
679 if (!dev->urb_ctl)
680 goto err_out;
681
682 /* get a handle to the interrupt data pipe */
683 pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
684 ret = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
685 if (ret != USB_PKT_LEN)
686 err("invalid payload size %d, expected %d", ret, USB_PKT_LEN);
687
688 /* initialise irq urb */
689 usb_fill_int_urb(dev->urb_irq, udev, pipe, dev->irq_data,
690 USB_PKT_LEN,
691 cm109_urb_irq_callback, dev, endpoint->bInterval);
692 dev->urb_irq->transfer_dma = dev->irq_dma;
693 dev->urb_irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
694 dev->urb_irq->dev = udev;
695
696 /* initialise ctl urb */
697 dev->ctl_req->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE |
698 USB_DIR_OUT;
699 dev->ctl_req->bRequest = USB_REQ_SET_CONFIGURATION;
700 dev->ctl_req->wValue = cpu_to_le16(0x200);
701 dev->ctl_req->wIndex = cpu_to_le16(interface->desc.bInterfaceNumber);
702 dev->ctl_req->wLength = cpu_to_le16(USB_PKT_LEN);
703
704 usb_fill_control_urb(dev->urb_ctl, udev, usb_sndctrlpipe(udev, 0),
705 (void *)dev->ctl_req, dev->ctl_data, USB_PKT_LEN,
706 cm109_urb_ctl_callback, dev);
707 dev->urb_ctl->setup_dma = dev->ctl_req_dma;
708 dev->urb_ctl->transfer_dma = dev->ctl_dma;
709 dev->urb_ctl->transfer_flags |= URB_NO_SETUP_DMA_MAP |
710 URB_NO_TRANSFER_DMA_MAP;
711 dev->urb_ctl->dev = udev;
712
713 /* find out the physical bus location */
714 usb_make_path(udev, dev->phys, sizeof(dev->phys));
715 strlcat(dev->phys, "/input0", sizeof(dev->phys));
716
717 /* register settings for the input device */
718 input_dev->name = nfo->name;
719 input_dev->phys = dev->phys;
720 usb_to_input_id(udev, &input_dev->id);
721 input_dev->dev.parent = &intf->dev;
722
723 input_set_drvdata(input_dev, dev);
724 input_dev->open = cm109_input_open;
725 input_dev->close = cm109_input_close;
726 input_dev->event = cm109_input_ev;
727
728 input_dev->keycode = dev->keymap;
729 input_dev->keycodesize = sizeof(unsigned char);
730 input_dev->keycodemax = ARRAY_SIZE(dev->keymap);
731
732 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_SND);
733 input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
734
735 /* register available key events */
736 for (i = 0; i < KEYMAP_SIZE; i++) {
737 unsigned short k = keymap(i);
738 dev->keymap[i] = k;
739 __set_bit(k, input_dev->keybit);
740 }
741 __clear_bit(KEY_RESERVED, input_dev->keybit);
742
743 error = input_register_device(dev->idev);
744 if (error)
745 goto err_out;
746
747 usb_set_intfdata(intf, dev);
748
749 return 0;
750
751 err_out:
752 input_free_device(input_dev);
753 cm109_usb_cleanup(dev);
754 return error;
755}
756
757static int cm109_usb_suspend(struct usb_interface *intf, pm_message_t message)
758{
759 struct cm109_dev *dev = usb_get_intfdata(intf);
760
761 dev_info(&intf->dev, "cm109: usb_suspend (event=%d)\n", message.event);
762
763 mutex_lock(&dev->pm_mutex);
764 cm109_stop_traffic(dev);
765 mutex_unlock(&dev->pm_mutex);
766
767 return 0;
768}
769
770static int cm109_usb_resume(struct usb_interface *intf)
771{
772 struct cm109_dev *dev = usb_get_intfdata(intf);
773
774 dev_info(&intf->dev, "cm109: usb_resume\n");
775
776 mutex_lock(&dev->pm_mutex);
777 cm109_restore_state(dev);
778 mutex_unlock(&dev->pm_mutex);
779
780 return 0;
781}
782
783static int cm109_usb_pre_reset(struct usb_interface *intf)
784{
785 struct cm109_dev *dev = usb_get_intfdata(intf);
786
787 mutex_lock(&dev->pm_mutex);
788
789 /*
790 * Make sure input events don't try to toggle buzzer
791 * while we are resetting
792 */
793 dev->resetting = 1;
794 smp_wmb();
795
796 cm109_stop_traffic(dev);
797
798 return 0;
799}
800
801static int cm109_usb_post_reset(struct usb_interface *intf)
802{
803 struct cm109_dev *dev = usb_get_intfdata(intf);
804
805 dev->resetting = 0;
806 smp_wmb();
807
808 cm109_restore_state(dev);
809
810 mutex_unlock(&dev->pm_mutex);
811
812 return 0;
813}
814
815static struct usb_driver cm109_driver = {
816 .name = "cm109",
817 .probe = cm109_usb_probe,
818 .disconnect = cm109_usb_disconnect,
819 .suspend = cm109_usb_suspend,
820 .resume = cm109_usb_resume,
821 .reset_resume = cm109_usb_resume,
822 .pre_reset = cm109_usb_pre_reset,
823 .post_reset = cm109_usb_post_reset,
824 .id_table = cm109_usb_table,
825 .supports_autosuspend = 1,
826};
827
828static int __init cm109_select_keymap(void)
829{
830 /* Load the phone keymap */
831 if (!strcasecmp(phone, "kip1000")) {
832 keymap = keymap_kip1000;
833 printk(KERN_INFO KBUILD_MODNAME ": "
834 "Keymap for Komunikate KIP1000 phone loaded\n");
835 } else if (!strcasecmp(phone, "gtalk")) {
836 keymap = keymap_gtalk;
837 printk(KERN_INFO KBUILD_MODNAME ": "
838 "Keymap for Genius G-talk phone loaded\n");
839 } else if (!strcasecmp(phone, "usbph01")) {
840 keymap = keymap_usbph01;
841 printk(KERN_INFO KBUILD_MODNAME ": "
842 "Keymap for Allied-Telesis Corega USBPH01 phone loaded\n");
843 } else {
844 printk(KERN_ERR KBUILD_MODNAME ": "
845 "Unsupported phone: %s\n", phone);
846 return -EINVAL;
847 }
848
849 return 0;
850}
851
852static int __init cm109_init(void)
853{
854 int err;
855
856 err = cm109_select_keymap();
857 if (err)
858 return err;
859
860 err = usb_register(&cm109_driver);
861 if (err)
862 return err;
863
864 printk(KERN_INFO KBUILD_MODNAME ": "
865 DRIVER_DESC ": " DRIVER_VERSION " (C) " DRIVER_AUTHOR "\n");
866
867 return 0;
868}
869
870static void __exit cm109_exit(void)
871{
872 usb_deregister(&cm109_driver);
873}
874
875module_init(cm109_init);
876module_exit(cm109_exit);
877
878MODULE_DEVICE_TABLE(usb, cm109_usb_table);
879
880MODULE_AUTHOR(DRIVER_AUTHOR);
881MODULE_DESCRIPTION(DRIVER_DESC);
882MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/map_to_7segment.h b/drivers/input/misc/map_to_7segment.h
deleted file mode 100644
index a424094d9fe2..000000000000
--- a/drivers/input/misc/map_to_7segment.h
+++ /dev/null
@@ -1,189 +0,0 @@
1/*
2 * drivers/usb/input/map_to_7segment.h
3 *
4 * Copyright (c) 2005 Henk Vergonet <Henk.Vergonet@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#ifndef MAP_TO_7SEGMENT_H
22#define MAP_TO_7SEGMENT_H
23
24/* This file provides translation primitives and tables for the conversion
25 * of (ASCII) characters to a 7-segments notation.
26 *
27 * The 7 segment's wikipedia notation below is used as standard.
28 * See: http://en.wikipedia.org/wiki/Seven_segment_display
29 *
30 * Notation: +-a-+
31 * f b
32 * +-g-+
33 * e c
34 * +-d-+
35 *
36 * Usage:
37 *
38 * Register a map variable, and fill it with a character set:
39 * static SEG7_DEFAULT_MAP(map_seg7);
40 *
41 *
42 * Then use for conversion:
43 * seg7 = map_to_seg7(&map_seg7, some_char);
44 * ...
45 *
46 * In device drivers it is recommended, if required, to make the char map
47 * accessible via the sysfs interface using the following scheme:
48 *
49 * static ssize_t show_map(struct device *dev, char *buf) {
50 * memcpy(buf, &map_seg7, sizeof(map_seg7));
51 * return sizeof(map_seg7);
52 * }
53 * static ssize_t store_map(struct device *dev, const char *buf, size_t cnt) {
54 * if(cnt != sizeof(map_seg7))
55 * return -EINVAL;
56 * memcpy(&map_seg7, buf, cnt);
57 * return cnt;
58 * }
59 * static DEVICE_ATTR(map_seg7, PERMS_RW, show_map, store_map);
60 *
61 * History:
62 * 2005-05-31 RFC linux-kernel@vger.kernel.org
63 */
64#include <linux/errno.h>
65
66
67#define BIT_SEG7_A 0
68#define BIT_SEG7_B 1
69#define BIT_SEG7_C 2
70#define BIT_SEG7_D 3
71#define BIT_SEG7_E 4
72#define BIT_SEG7_F 5
73#define BIT_SEG7_G 6
74#define BIT_SEG7_RESERVED 7
75
76struct seg7_conversion_map {
77 unsigned char table[128];
78};
79
80static inline int map_to_seg7(struct seg7_conversion_map *map, int c)
81{
82 return c >= 0 && c < sizeof(map->table) ? map->table[c] : -EINVAL;
83}
84
85#define SEG7_CONVERSION_MAP(_name, _map) \
86 struct seg7_conversion_map _name = { .table = { _map } }
87
88/*
89 * It is recommended to use a facility that allows user space to redefine
90 * custom character sets for LCD devices. Please use a sysfs interface
91 * as described above.
92 */
93#define MAP_TO_SEG7_SYSFS_FILE "map_seg7"
94
95/*******************************************************************************
96 * ASCII conversion table
97 ******************************************************************************/
98
99#define _SEG7(l,a,b,c,d,e,f,g) \
100 ( a<<BIT_SEG7_A | b<<BIT_SEG7_B | c<<BIT_SEG7_C | d<<BIT_SEG7_D | \
101 e<<BIT_SEG7_E | f<<BIT_SEG7_F | g<<BIT_SEG7_G )
102
103#define _MAP_0_32_ASCII_SEG7_NON_PRINTABLE \
104 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
105
106#define _MAP_33_47_ASCII_SEG7_SYMBOL \
107 _SEG7('!',0,0,0,0,1,1,0), _SEG7('"',0,1,0,0,0,1,0), _SEG7('#',0,1,1,0,1,1,0),\
108 _SEG7('$',1,0,1,1,0,1,1), _SEG7('%',0,0,1,0,0,1,0), _SEG7('&',1,0,1,1,1,1,1),\
109 _SEG7('\'',0,0,0,0,0,1,0),_SEG7('(',1,0,0,1,1,1,0), _SEG7(')',1,1,1,1,0,0,0),\
110 _SEG7('*',0,1,1,0,1,1,1), _SEG7('+',0,1,1,0,0,0,1), _SEG7(',',0,0,0,0,1,0,0),\
111 _SEG7('-',0,0,0,0,0,0,1), _SEG7('.',0,0,0,0,1,0,0), _SEG7('/',0,1,0,0,1,0,1),
112
113#define _MAP_48_57_ASCII_SEG7_NUMERIC \
114 _SEG7('0',1,1,1,1,1,1,0), _SEG7('1',0,1,1,0,0,0,0), _SEG7('2',1,1,0,1,1,0,1),\
115 _SEG7('3',1,1,1,1,0,0,1), _SEG7('4',0,1,1,0,0,1,1), _SEG7('5',1,0,1,1,0,1,1),\
116 _SEG7('6',1,0,1,1,1,1,1), _SEG7('7',1,1,1,0,0,0,0), _SEG7('8',1,1,1,1,1,1,1),\
117 _SEG7('9',1,1,1,1,0,1,1),
118
119#define _MAP_58_64_ASCII_SEG7_SYMBOL \
120 _SEG7(':',0,0,0,1,0,0,1), _SEG7(';',0,0,0,1,0,0,1), _SEG7('<',1,0,0,0,0,1,1),\
121 _SEG7('=',0,0,0,1,0,0,1), _SEG7('>',1,1,0,0,0,0,1), _SEG7('?',1,1,1,0,0,1,0),\
122 _SEG7('@',1,1,0,1,1,1,1),
123
124#define _MAP_65_90_ASCII_SEG7_ALPHA_UPPR \
125 _SEG7('A',1,1,1,0,1,1,1), _SEG7('B',1,1,1,1,1,1,1), _SEG7('C',1,0,0,1,1,1,0),\
126 _SEG7('D',1,1,1,1,1,1,0), _SEG7('E',1,0,0,1,1,1,1), _SEG7('F',1,0,0,0,1,1,1),\
127 _SEG7('G',1,1,1,1,0,1,1), _SEG7('H',0,1,1,0,1,1,1), _SEG7('I',0,1,1,0,0,0,0),\
128 _SEG7('J',0,1,1,1,0,0,0), _SEG7('K',0,1,1,0,1,1,1), _SEG7('L',0,0,0,1,1,1,0),\
129 _SEG7('M',1,1,1,0,1,1,0), _SEG7('N',1,1,1,0,1,1,0), _SEG7('O',1,1,1,1,1,1,0),\
130 _SEG7('P',1,1,0,0,1,1,1), _SEG7('Q',1,1,1,1,1,1,0), _SEG7('R',1,1,1,0,1,1,1),\
131 _SEG7('S',1,0,1,1,0,1,1), _SEG7('T',0,0,0,1,1,1,1), _SEG7('U',0,1,1,1,1,1,0),\
132 _SEG7('V',0,1,1,1,1,1,0), _SEG7('W',0,1,1,1,1,1,1), _SEG7('X',0,1,1,0,1,1,1),\
133 _SEG7('Y',0,1,1,0,0,1,1), _SEG7('Z',1,1,0,1,1,0,1),
134
135#define _MAP_91_96_ASCII_SEG7_SYMBOL \
136 _SEG7('[',1,0,0,1,1,1,0), _SEG7('\\',0,0,1,0,0,1,1),_SEG7(']',1,1,1,1,0,0,0),\
137 _SEG7('^',1,1,0,0,0,1,0), _SEG7('_',0,0,0,1,0,0,0), _SEG7('`',0,1,0,0,0,0,0),
138
139#define _MAP_97_122_ASCII_SEG7_ALPHA_LOWER \
140 _SEG7('A',1,1,1,0,1,1,1), _SEG7('b',0,0,1,1,1,1,1), _SEG7('c',0,0,0,1,1,0,1),\
141 _SEG7('d',0,1,1,1,1,0,1), _SEG7('E',1,0,0,1,1,1,1), _SEG7('F',1,0,0,0,1,1,1),\
142 _SEG7('G',1,1,1,1,0,1,1), _SEG7('h',0,0,1,0,1,1,1), _SEG7('i',0,0,1,0,0,0,0),\
143 _SEG7('j',0,0,1,1,0,0,0), _SEG7('k',0,0,1,0,1,1,1), _SEG7('L',0,0,0,1,1,1,0),\
144 _SEG7('M',1,1,1,0,1,1,0), _SEG7('n',0,0,1,0,1,0,1), _SEG7('o',0,0,1,1,1,0,1),\
145 _SEG7('P',1,1,0,0,1,1,1), _SEG7('q',1,1,1,0,0,1,1), _SEG7('r',0,0,0,0,1,0,1),\
146 _SEG7('S',1,0,1,1,0,1,1), _SEG7('T',0,0,0,1,1,1,1), _SEG7('u',0,0,1,1,1,0,0),\
147 _SEG7('v',0,0,1,1,1,0,0), _SEG7('W',0,1,1,1,1,1,1), _SEG7('X',0,1,1,0,1,1,1),\
148 _SEG7('y',0,1,1,1,0,1,1), _SEG7('Z',1,1,0,1,1,0,1),
149
150#define _MAP_123_126_ASCII_SEG7_SYMBOL \
151 _SEG7('{',1,0,0,1,1,1,0), _SEG7('|',0,0,0,0,1,1,0), _SEG7('}',1,1,1,1,0,0,0),\
152 _SEG7('~',1,0,0,0,0,0,0),
153
154/* Maps */
155
156/* This set tries to map as close as possible to the visible characteristics
157 * of the ASCII symbol, lowercase and uppercase letters may differ in
158 * presentation on the display.
159 */
160#define MAP_ASCII7SEG_ALPHANUM \
161 _MAP_0_32_ASCII_SEG7_NON_PRINTABLE \
162 _MAP_33_47_ASCII_SEG7_SYMBOL \
163 _MAP_48_57_ASCII_SEG7_NUMERIC \
164 _MAP_58_64_ASCII_SEG7_SYMBOL \
165 _MAP_65_90_ASCII_SEG7_ALPHA_UPPR \
166 _MAP_91_96_ASCII_SEG7_SYMBOL \
167 _MAP_97_122_ASCII_SEG7_ALPHA_LOWER \
168 _MAP_123_126_ASCII_SEG7_SYMBOL
169
170/* This set tries to map as close as possible to the symbolic characteristics
171 * of the ASCII character for maximum discrimination.
172 * For now this means all alpha chars are in lower case representations.
173 * (This for example facilitates the use of hex numbers with uppercase input.)
174 */
175#define MAP_ASCII7SEG_ALPHANUM_LC \
176 _MAP_0_32_ASCII_SEG7_NON_PRINTABLE \
177 _MAP_33_47_ASCII_SEG7_SYMBOL \
178 _MAP_48_57_ASCII_SEG7_NUMERIC \
179 _MAP_58_64_ASCII_SEG7_SYMBOL \
180 _MAP_97_122_ASCII_SEG7_ALPHA_LOWER \
181 _MAP_91_96_ASCII_SEG7_SYMBOL \
182 _MAP_97_122_ASCII_SEG7_ALPHA_LOWER \
183 _MAP_123_126_ASCII_SEG7_SYMBOL
184
185#define SEG7_DEFAULT_MAP(_name) \
186 SEG7_CONVERSION_MAP(_name,MAP_ASCII7SEG_ALPHANUM)
187
188#endif /* MAP_TO_7SEGMENT_H */
189
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c
index fe268be3293b..7c8957dd22c0 100644
--- a/drivers/input/misc/wistron_btns.c
+++ b/drivers/input/misc/wistron_btns.c
@@ -277,6 +277,16 @@ static struct key_entry keymap_fs_amilo_pro_v2000[] __initdata = {
277 { KE_END, 0 } 277 { KE_END, 0 }
278}; 278};
279 279
280static struct key_entry keymap_fs_amilo_pro_v3505[] __initdata = {
281 { KE_KEY, 0x01, {KEY_HELP} }, /* Fn+F1 */
282 { KE_KEY, 0x06, {KEY_DISPLAYTOGGLE} }, /* Fn+F4 */
283 { KE_BLUETOOTH, 0x30 }, /* Fn+F10 */
284 { KE_KEY, 0x31, {KEY_MAIL} }, /* mail button */
285 { KE_KEY, 0x36, {KEY_WWW} }, /* www button */
286 { KE_WIFI, 0x78 }, /* satelite dish button */
287 { KE_END, 0 }
288};
289
280static struct key_entry keymap_fujitsu_n3510[] __initdata = { 290static struct key_entry keymap_fujitsu_n3510[] __initdata = {
281 { KE_KEY, 0x11, {KEY_PROG1} }, 291 { KE_KEY, 0x11, {KEY_PROG1} },
282 { KE_KEY, 0x12, {KEY_PROG2} }, 292 { KE_KEY, 0x12, {KEY_PROG2} },
@@ -618,6 +628,15 @@ static struct dmi_system_id dmi_ids[] __initdata = {
618 }, 628 },
619 { 629 {
620 .callback = dmi_matched, 630 .callback = dmi_matched,
631 .ident = "Fujitsu-Siemens Amilo Pro Edition V3505",
632 .matches = {
633 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
634 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro Edition V3505"),
635 },
636 .driver_data = keymap_fs_amilo_pro_v3505
637 },
638 {
639 .callback = dmi_matched,
621 .ident = "Fujitsu-Siemens Amilo M7400", 640 .ident = "Fujitsu-Siemens Amilo M7400",
622 .matches = { 641 .matches = {
623 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), 642 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
diff --git a/drivers/input/misc/yealink.c b/drivers/input/misc/yealink.c
index facefd3dba29..11b5c7e84ed1 100644
--- a/drivers/input/misc/yealink.c
+++ b/drivers/input/misc/yealink.c
@@ -52,8 +52,8 @@
52#include <linux/module.h> 52#include <linux/module.h>
53#include <linux/rwsem.h> 53#include <linux/rwsem.h>
54#include <linux/usb/input.h> 54#include <linux/usb/input.h>
55#include <linux/map_to_7segment.h>
55 56
56#include "map_to_7segment.h"
57#include "yealink.h" 57#include "yealink.h"
58 58
59#define DRIVER_VERSION "yld-20051230" 59#define DRIVER_VERSION "yld-20051230"
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
index f996546fc443..f488b6852baf 100644
--- a/drivers/input/mouse/Kconfig
+++ b/drivers/input/mouse/Kconfig
@@ -96,6 +96,16 @@ config MOUSE_PS2_TOUCHKIT
96 96
97 If unsure, say N. 97 If unsure, say N.
98 98
99config MOUSE_PS2_OLPC
100 bool "OLPC PS/2 mouse protocol extension"
101 depends on MOUSE_PS2 && OLPC
102 help
103 Say Y here if you have an OLPC XO-1 laptop (with built-in
104 PS/2 touchpad/tablet device). The manufacturer calls the
105 touchpad an HGPK.
106
107 If unsure, say N.
108
99config MOUSE_SERIAL 109config MOUSE_SERIAL
100 tristate "Serial mouse" 110 tristate "Serial mouse"
101 select SERIO 111 select SERIO
diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile
index d4d202516090..8e6e69097801 100644
--- a/drivers/input/mouse/Makefile
+++ b/drivers/input/mouse/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o
21psmouse-objs := psmouse-base.o synaptics.o 21psmouse-objs := psmouse-base.o synaptics.o
22 22
23psmouse-$(CONFIG_MOUSE_PS2_ALPS) += alps.o 23psmouse-$(CONFIG_MOUSE_PS2_ALPS) += alps.o
24psmouse-$(CONFIG_MOUSE_PS2_OLPC) += hgpk.o
24psmouse-$(CONFIG_MOUSE_PS2_LOGIPS2PP) += logips2pp.o 25psmouse-$(CONFIG_MOUSE_PS2_LOGIPS2PP) += logips2pp.o
25psmouse-$(CONFIG_MOUSE_PS2_LIFEBOOK) += lifebook.o 26psmouse-$(CONFIG_MOUSE_PS2_LIFEBOOK) += lifebook.o
26psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT) += trackpoint.o 27psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT) += trackpoint.o
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 385e32bcf6a6..cbedf957cc58 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -54,6 +54,7 @@ static const struct alps_model_info alps_model_data[] = {
54 { { 0x20, 0x02, 0x0e }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */ 54 { { 0x20, 0x02, 0x0e }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */
55 { { 0x22, 0x02, 0x0a }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, 55 { { 0x22, 0x02, 0x0a }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT },
56 { { 0x22, 0x02, 0x14 }, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */ 56 { { 0x22, 0x02, 0x14 }, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */
57 { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude E6500 */
57 { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FW_BK_1 } /* Dell Vostro 1400 */ 58 { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FW_BK_1 } /* Dell Vostro 1400 */
58}; 59};
59 60
diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c
index 1f41ae94f26b..079816e6b23b 100644
--- a/drivers/input/mouse/appletouch.c
+++ b/drivers/input/mouse/appletouch.c
@@ -136,12 +136,28 @@ MODULE_DEVICE_TABLE(usb, atp_table);
136#define ATP_GEYSER_MODE_REQUEST_INDEX 0 136#define ATP_GEYSER_MODE_REQUEST_INDEX 0
137#define ATP_GEYSER_MODE_VENDOR_VALUE 0x04 137#define ATP_GEYSER_MODE_VENDOR_VALUE 0x04
138 138
139/**
140 * enum atp_status_bits - status bit meanings
141 *
142 * These constants represent the meaning of the status bits.
143 * (only Geyser 3/4)
144 *
145 * @ATP_STATUS_BUTTON: The button was pressed
146 * @ATP_STATUS_BASE_UPDATE: Update of the base values (untouched pad)
147 * @ATP_STATUS_FROM_RESET: Reset previously performed
148 */
149enum atp_status_bits {
150 ATP_STATUS_BUTTON = BIT(0),
151 ATP_STATUS_BASE_UPDATE = BIT(2),
152 ATP_STATUS_FROM_RESET = BIT(4),
153};
154
139/* Structure to hold all of our device specific stuff */ 155/* Structure to hold all of our device specific stuff */
140struct atp { 156struct atp {
141 char phys[64]; 157 char phys[64];
142 struct usb_device *udev; /* usb device */ 158 struct usb_device *udev; /* usb device */
143 struct urb *urb; /* usb request block */ 159 struct urb *urb; /* usb request block */
144 signed char *data; /* transferred data */ 160 u8 *data; /* transferred data */
145 struct input_dev *input; /* input dev */ 161 struct input_dev *input; /* input dev */
146 enum atp_touchpad_type type; /* type of touchpad */ 162 enum atp_touchpad_type type; /* type of touchpad */
147 bool open; 163 bool open;
@@ -251,8 +267,6 @@ static void atp_reinit(struct work_struct *work)
251 int retval; 267 int retval;
252 268
253 dprintk("appletouch: putting appletouch to sleep (reinit)\n"); 269 dprintk("appletouch: putting appletouch to sleep (reinit)\n");
254 dev->idlecount = 0;
255
256 atp_geyser_init(udev); 270 atp_geyser_init(udev);
257 271
258 retval = usb_submit_urb(dev->urb, GFP_ATOMIC); 272 retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
@@ -327,11 +341,14 @@ static inline void atp_report_fingers(struct input_dev *input, int fingers)
327 input_report_key(input, BTN_TOOL_TRIPLETAP, fingers > 2); 341 input_report_key(input, BTN_TOOL_TRIPLETAP, fingers > 2);
328} 342}
329 343
330static void atp_complete(struct urb *urb) 344/* Check URB status and for correct length of data package */
345
346#define ATP_URB_STATUS_SUCCESS 0
347#define ATP_URB_STATUS_ERROR 1
348#define ATP_URB_STATUS_ERROR_FATAL 2
349
350static int atp_status_check(struct urb *urb)
331{ 351{
332 int x, y, x_z, y_z, x_f, y_f;
333 int retval, i, j;
334 int key;
335 struct atp *dev = urb->context; 352 struct atp *dev = urb->context;
336 353
337 switch (urb->status) { 354 switch (urb->status) {
@@ -351,11 +368,12 @@ static void atp_complete(struct urb *urb)
351 /* This urb is terminated, clean up */ 368 /* This urb is terminated, clean up */
352 dbg("atp_complete: urb shutting down with status: %d", 369 dbg("atp_complete: urb shutting down with status: %d",
353 urb->status); 370 urb->status);
354 return; 371 return ATP_URB_STATUS_ERROR_FATAL;
372
355 default: 373 default:
356 dbg("atp_complete: nonzero urb status received: %d", 374 dbg("atp_complete: nonzero urb status received: %d",
357 urb->status); 375 urb->status);
358 goto exit; 376 return ATP_URB_STATUS_ERROR;
359 } 377 }
360 378
361 /* drop incomplete datasets */ 379 /* drop incomplete datasets */
@@ -363,30 +381,33 @@ static void atp_complete(struct urb *urb)
363 dprintk("appletouch: incomplete data package" 381 dprintk("appletouch: incomplete data package"
364 " (first byte: %d, length: %d).\n", 382 " (first byte: %d, length: %d).\n",
365 dev->data[0], dev->urb->actual_length); 383 dev->data[0], dev->urb->actual_length);
366 goto exit; 384 return ATP_URB_STATUS_ERROR;
367 } 385 }
368 386
369 /* reorder the sensors values */ 387 return ATP_URB_STATUS_SUCCESS;
370 if (dev->type == ATP_GEYSER3 || dev->type == ATP_GEYSER4) { 388}
371 memset(dev->xy_cur, 0, sizeof(dev->xy_cur));
372 389
373 /* 390/*
374 * The values are laid out like this: 391 * USB interrupt callback functions
375 * -, Y1, Y2, -, Y3, Y4, -, ..., -, X1, X2, -, X3, X4, ... 392 */
376 * '-' is an unused value.
377 */
378 393
379 /* read X values */ 394/* Interrupt function for older touchpads: FOUNTAIN/GEYSER1/GEYSER2 */
380 for (i = 0, j = 19; i < 20; i += 2, j += 3) { 395
381 dev->xy_cur[i] = dev->data[j + 1]; 396static void atp_complete_geyser_1_2(struct urb *urb)
382 dev->xy_cur[i + 1] = dev->data[j + 2]; 397{
383 } 398 int x, y, x_z, y_z, x_f, y_f;
384 /* read Y values */ 399 int retval, i, j;
385 for (i = 0, j = 1; i < 9; i += 2, j += 3) { 400 int key;
386 dev->xy_cur[ATP_XSENSORS + i] = dev->data[j + 1]; 401 struct atp *dev = urb->context;
387 dev->xy_cur[ATP_XSENSORS + i + 1] = dev->data[j + 2]; 402 int status = atp_status_check(urb);
388 } 403
389 } else if (dev->type == ATP_GEYSER2) { 404 if (status == ATP_URB_STATUS_ERROR_FATAL)
405 return;
406 else if (status == ATP_URB_STATUS_ERROR)
407 goto exit;
408
409 /* reorder the sensors values */
410 if (dev->type == ATP_GEYSER2) {
390 memset(dev->xy_cur, 0, sizeof(dev->xy_cur)); 411 memset(dev->xy_cur, 0, sizeof(dev->xy_cur));
391 412
392 /* 413 /*
@@ -427,34 +448,40 @@ static void atp_complete(struct urb *urb)
427 /* first sample */ 448 /* first sample */
428 dev->valid = true; 449 dev->valid = true;
429 dev->x_old = dev->y_old = -1; 450 dev->x_old = dev->y_old = -1;
451
452 /* Store first sample */
430 memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old)); 453 memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old));
431 454
432 if (dev->size_detect_done || 455 /* Perform size detection, if not done already */
433 dev->type == ATP_GEYSER3) /* No 17" Macbooks (yet) */ 456 if (!dev->size_detect_done) {
434 goto exit; 457
458 /* 17" Powerbooks have extra X sensors */
459 for (i = (dev->type == ATP_GEYSER2 ? 15 : 16);
460 i < ATP_XSENSORS; i++) {
461 if (!dev->xy_cur[i])
462 continue;
463
464 printk(KERN_INFO
465 "appletouch: 17\" model detected.\n");
466
467 if (dev->type == ATP_GEYSER2)
468 input_set_abs_params(dev->input, ABS_X,
469 0,
470 (20 - 1) *
471 ATP_XFACT - 1,
472 ATP_FUZZ, 0);
473 else
474 input_set_abs_params(dev->input, ABS_X,
475 0,
476 (26 - 1) *
477 ATP_XFACT - 1,
478 ATP_FUZZ, 0);
479 break;
480 }
435 481
436 /* 17" Powerbooks have extra X sensors */ 482 dev->size_detect_done = 1;
437 for (i = (dev->type == ATP_GEYSER2 ? 15 : 16); 483 goto exit;
438 i < ATP_XSENSORS; i++) {
439 if (!dev->xy_cur[i])
440 continue;
441
442 printk(KERN_INFO "appletouch: 17\" model detected.\n");
443 if (dev->type == ATP_GEYSER2)
444 input_set_abs_params(dev->input, ABS_X, 0,
445 (20 - 1) *
446 ATP_XFACT - 1,
447 ATP_FUZZ, 0);
448 else
449 input_set_abs_params(dev->input, ABS_X, 0,
450 (ATP_XSENSORS - 1) *
451 ATP_XFACT - 1,
452 ATP_FUZZ, 0);
453 break;
454 } 484 }
455
456 dev->size_detect_done = 1;
457 goto exit;
458 } 485 }
459 486
460 for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) { 487 for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) {
@@ -475,7 +502,118 @@ static void atp_complete(struct urb *urb)
475 ATP_XFACT, &x_z, &x_f); 502 ATP_XFACT, &x_z, &x_f);
476 y = atp_calculate_abs(dev->xy_acc + ATP_XSENSORS, ATP_YSENSORS, 503 y = atp_calculate_abs(dev->xy_acc + ATP_XSENSORS, ATP_YSENSORS,
477 ATP_YFACT, &y_z, &y_f); 504 ATP_YFACT, &y_z, &y_f);
478 key = dev->data[dev->datalen - 1] & 1; 505 key = dev->data[dev->datalen - 1] & ATP_STATUS_BUTTON;
506
507 if (x && y) {
508 if (dev->x_old != -1) {
509 x = (dev->x_old * 3 + x) >> 2;
510 y = (dev->y_old * 3 + y) >> 2;
511 dev->x_old = x;
512 dev->y_old = y;
513
514 if (debug > 1)
515 printk(KERN_DEBUG "appletouch: "
516 "X: %3d Y: %3d Xz: %3d Yz: %3d\n",
517 x, y, x_z, y_z);
518
519 input_report_key(dev->input, BTN_TOUCH, 1);
520 input_report_abs(dev->input, ABS_X, x);
521 input_report_abs(dev->input, ABS_Y, y);
522 input_report_abs(dev->input, ABS_PRESSURE,
523 min(ATP_PRESSURE, x_z + y_z));
524 atp_report_fingers(dev->input, max(x_f, y_f));
525 }
526 dev->x_old = x;
527 dev->y_old = y;
528
529 } else if (!x && !y) {
530
531 dev->x_old = dev->y_old = -1;
532 input_report_key(dev->input, BTN_TOUCH, 0);
533 input_report_abs(dev->input, ABS_PRESSURE, 0);
534 atp_report_fingers(dev->input, 0);
535
536 /* reset the accumulator on release */
537 memset(dev->xy_acc, 0, sizeof(dev->xy_acc));
538 }
539
540 input_report_key(dev->input, BTN_LEFT, key);
541 input_sync(dev->input);
542
543 exit:
544 retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
545 if (retval)
546 err("atp_complete: usb_submit_urb failed with result %d",
547 retval);
548}
549
550/* Interrupt function for older touchpads: GEYSER3/GEYSER4 */
551
552static void atp_complete_geyser_3_4(struct urb *urb)
553{
554 int x, y, x_z, y_z, x_f, y_f;
555 int retval, i, j;
556 int key;
557 struct atp *dev = urb->context;
558 int status = atp_status_check(urb);
559
560 if (status == ATP_URB_STATUS_ERROR_FATAL)
561 return;
562 else if (status == ATP_URB_STATUS_ERROR)
563 goto exit;
564
565 /* Reorder the sensors values:
566 *
567 * The values are laid out like this:
568 * -, Y1, Y2, -, Y3, Y4, -, ..., -, X1, X2, -, X3, X4, ...
569 * '-' is an unused value.
570 */
571
572 /* read X values */
573 for (i = 0, j = 19; i < 20; i += 2, j += 3) {
574 dev->xy_cur[i] = dev->data[j + 1];
575 dev->xy_cur[i + 1] = dev->data[j + 2];
576 }
577 /* read Y values */
578 for (i = 0, j = 1; i < 9; i += 2, j += 3) {
579 dev->xy_cur[ATP_XSENSORS + i] = dev->data[j + 1];
580 dev->xy_cur[ATP_XSENSORS + i + 1] = dev->data[j + 2];
581 }
582
583 dbg_dump("sample", dev->xy_cur);
584
585 /* Just update the base values (i.e. touchpad in untouched state) */
586 if (dev->data[dev->datalen - 1] & ATP_STATUS_BASE_UPDATE) {
587
588 dprintk(KERN_DEBUG "appletouch: updated base values\n");
589
590 memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old));
591 goto exit;
592 }
593
594 for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) {
595 /* calculate the change */
596 dev->xy_acc[i] = dev->xy_cur[i] - dev->xy_old[i];
597
598 /* this is a round-robin value, so couple with that */
599 if (dev->xy_acc[i] > 127)
600 dev->xy_acc[i] -= 256;
601
602 if (dev->xy_acc[i] < -127)
603 dev->xy_acc[i] += 256;
604
605 /* prevent down drifting */
606 if (dev->xy_acc[i] < 0)
607 dev->xy_acc[i] = 0;
608 }
609
610 dbg_dump("accumulator", dev->xy_acc);
611
612 x = atp_calculate_abs(dev->xy_acc, ATP_XSENSORS,
613 ATP_XFACT, &x_z, &x_f);
614 y = atp_calculate_abs(dev->xy_acc + ATP_XSENSORS, ATP_YSENSORS,
615 ATP_YFACT, &y_z, &y_f);
616 key = dev->data[dev->datalen - 1] & ATP_STATUS_BUTTON;
479 617
480 if (x && y) { 618 if (x && y) {
481 if (dev->x_old != -1) { 619 if (dev->x_old != -1) {
@@ -514,28 +652,27 @@ static void atp_complete(struct urb *urb)
514 input_sync(dev->input); 652 input_sync(dev->input);
515 653
516 /* 654 /*
517 * Many Geysers will continue to send packets continually after 655 * Geysers 3/4 will continue to send packets continually after
518 * the first touch unless reinitialised. Do so if it's been 656 * the first touch unless reinitialised. Do so if it's been
519 * idle for a while in order to avoid waking the kernel up 657 * idle for a while in order to avoid waking the kernel up
520 * several hundred times a second. Re-initialization does not 658 * several hundred times a second.
521 * work on Fountain touchpads.
522 */ 659 */
523 if (dev->type != ATP_FOUNTAIN) { 660
524 /* 661 /*
525 * Button must not be pressed when entering suspend, 662 * Button must not be pressed when entering suspend,
526 * otherwise we will never release the button. 663 * otherwise we will never release the button.
527 */ 664 */
528 if (!x && !y && !key) { 665 if (!x && !y && !key) {
529 dev->idlecount++; 666 dev->idlecount++;
530 if (dev->idlecount == 10) { 667 if (dev->idlecount == 10) {
531 dev->valid = false; 668 dev->x_old = dev->y_old = -1;
532 schedule_work(&dev->work);
533 /* Don't resubmit urb here, wait for reinit */
534 return;
535 }
536 } else
537 dev->idlecount = 0; 669 dev->idlecount = 0;
538 } 670 schedule_work(&dev->work);
671 /* Don't resubmit urb here, wait for reinit */
672 return;
673 }
674 } else
675 dev->idlecount = 0;
539 676
540 exit: 677 exit:
541 retval = usb_submit_urb(dev->urb, GFP_ATOMIC); 678 retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
@@ -632,9 +769,19 @@ static int atp_probe(struct usb_interface *iface,
632 if (!dev->data) 769 if (!dev->data)
633 goto err_free_urb; 770 goto err_free_urb;
634 771
635 usb_fill_int_urb(dev->urb, udev, 772 /* Select the USB complete (callback) function */
636 usb_rcvintpipe(udev, int_in_endpointAddr), 773 if (dev->type == ATP_FOUNTAIN ||
637 dev->data, dev->datalen, atp_complete, dev, 1); 774 dev->type == ATP_GEYSER1 ||
775 dev->type == ATP_GEYSER2)
776 usb_fill_int_urb(dev->urb, udev,
777 usb_rcvintpipe(udev, int_in_endpointAddr),
778 dev->data, dev->datalen,
779 atp_complete_geyser_1_2, dev, 1);
780 else
781 usb_fill_int_urb(dev->urb, udev,
782 usb_rcvintpipe(udev, int_in_endpointAddr),
783 dev->data, dev->datalen,
784 atp_complete_geyser_3_4, dev, 1);
638 785
639 error = atp_handle_geyser(dev); 786 error = atp_handle_geyser(dev);
640 if (error) 787 if (error)
@@ -751,8 +898,6 @@ static int atp_suspend(struct usb_interface *iface, pm_message_t message)
751 struct atp *dev = usb_get_intfdata(iface); 898 struct atp *dev = usb_get_intfdata(iface);
752 899
753 usb_kill_urb(dev->urb); 900 usb_kill_urb(dev->urb);
754 dev->valid = false;
755
756 return 0; 901 return 0;
757} 902}
758 903
diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c
new file mode 100644
index 000000000000..e82d34201e97
--- /dev/null
+++ b/drivers/input/mouse/hgpk.c
@@ -0,0 +1,477 @@
1/*
2 * OLPC HGPK (XO-1) touchpad PS/2 mouse driver
3 *
4 * Copyright (c) 2006-2008 One Laptop Per Child
5 * Authors:
6 * Zephaniah E. Hull
7 * Andres Salomon <dilinger@debian.org>
8 *
9 * This driver is partly based on the ALPS driver, which is:
10 *
11 * Copyright (c) 2003 Neil Brown <neilb@cse.unsw.edu.au>
12 * Copyright (c) 2003-2005 Peter Osterlund <petero2@telia.com>
13 * Copyright (c) 2004 Dmitry Torokhov <dtor@mail.ru>
14 * Copyright (c) 2005 Vojtech Pavlik <vojtech@suse.cz>
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License version 2 as
18 * published by the Free Software Foundation.
19 */
20
21/*
22 * The spec from ALPS is available from
23 * <http://wiki.laptop.org/go/Touch_Pad/Tablet>. It refers to this
24 * device as HGPK (Hybrid GS, PT, and Keymatrix).
25 *
26 * The earliest versions of the device had simultaneous reporting; that
27 * was removed. After that, the device used the Advanced Mode GS/PT streaming
28 * stuff. That turned out to be too buggy to support, so we've finally
29 * switched to Mouse Mode (which utilizes only the center 1/3 of the touchpad).
30 */
31
32#define DEBUG
33#include <linux/input.h>
34#include <linux/serio.h>
35#include <linux/libps2.h>
36#include <linux/delay.h>
37#include <asm/olpc.h>
38
39#include "psmouse.h"
40#include "hgpk.h"
41
42static int tpdebug;
43module_param(tpdebug, int, 0644);
44MODULE_PARM_DESC(tpdebug, "enable debugging, dumping packets to KERN_DEBUG.");
45
46static int recalib_delta = 100;
47module_param(recalib_delta, int, 0644);
48MODULE_PARM_DESC(recalib_delta,
49 "packets containing a delta this large will cause a recalibration.");
50
51/*
52 * When the touchpad gets ultra-sensitive, one can keep their finger 1/2"
53 * above the pad and still have it send packets. This causes a jump cursor
54 * when one places their finger on the pad. We can probably detect the
55 * jump as we see a large deltas (>= 100px). In mouse mode, I've been
56 * unable to even come close to 100px deltas during normal usage, so I think
57 * this threshold is safe. If a large delta occurs, trigger a recalibration.
58 */
59static void hgpk_jumpy_hack(struct psmouse *psmouse, int x, int y)
60{
61 struct hgpk_data *priv = psmouse->private;
62
63 if (abs(x) > recalib_delta || abs(y) > recalib_delta) {
64 hgpk_err(psmouse, ">%dpx jump detected (%d,%d)\n",
65 recalib_delta, x, y);
66 /* My car gets forty rods to the hogshead and that's the
67 * way I likes it! */
68 psmouse_queue_work(psmouse, &priv->recalib_wq,
69 msecs_to_jiffies(1000));
70 }
71}
72
73/*
74 * We have no idea why this particular hardware bug occurs. The touchpad
75 * will randomly start spewing packets without anything touching the
76 * pad. This wouldn't necessarily be bad, but it's indicative of a
77 * severely miscalibrated pad; attempting to use the touchpad while it's
78 * spewing means the cursor will jump all over the place, and act "drunk".
79 *
80 * The packets that are spewed tend to all have deltas between -2 and 2, and
81 * the cursor will move around without really going very far. It will
82 * tend to end up in the same location; if we tally up the changes over
83 * 100 packets, we end up w/ a final delta of close to 0. This happens
84 * pretty regularly when the touchpad is spewing, and is pretty hard to
85 * manually trigger (at least for *my* fingers). So, it makes a perfect
86 * scheme for detecting spews.
87 */
88static void hgpk_spewing_hack(struct psmouse *psmouse,
89 int l, int r, int x, int y)
90{
91 struct hgpk_data *priv = psmouse->private;
92
93 /* ignore button press packets; many in a row could trigger
94 * a false-positive! */
95 if (l || r)
96 return;
97
98 priv->x_tally += x;
99 priv->y_tally += y;
100
101 if (++priv->count > 100) {
102 if (abs(priv->x_tally) < 3 && abs(priv->y_tally) < 3) {
103 hgpk_dbg(psmouse, "packet spew detected (%d,%d)\n",
104 priv->x_tally, priv->y_tally);
105 psmouse_queue_work(psmouse, &priv->recalib_wq,
106 msecs_to_jiffies(1000));
107 }
108 /* reset every 100 packets */
109 priv->count = 0;
110 priv->x_tally = 0;
111 priv->y_tally = 0;
112 }
113}
114
115/*
116 * HGPK Mouse Mode format (standard mouse format, sans middle button)
117 *
118 * byte 0: y-over x-over y-neg x-neg 1 0 swr swl
119 * byte 1: x7 x6 x5 x4 x3 x2 x1 x0
120 * byte 2: y7 y6 y5 y4 y3 y2 y1 y0
121 *
122 * swr/swl are the left/right buttons.
123 * x-neg/y-neg are the x and y delta negative bits
124 * x-over/y-over are the x and y overflow bits
125 */
126static int hgpk_validate_byte(unsigned char *packet)
127{
128 return (packet[0] & 0x0C) == 0x08;
129}
130
131static void hgpk_process_packet(struct psmouse *psmouse)
132{
133 struct input_dev *dev = psmouse->dev;
134 unsigned char *packet = psmouse->packet;
135 int x, y, left, right;
136
137 left = packet[0] & 1;
138 right = (packet[0] >> 1) & 1;
139
140 x = packet[1] - ((packet[0] << 4) & 0x100);
141 y = ((packet[0] << 3) & 0x100) - packet[2];
142
143 hgpk_jumpy_hack(psmouse, x, y);
144 hgpk_spewing_hack(psmouse, left, right, x, y);
145
146 if (tpdebug)
147 hgpk_dbg(psmouse, "l=%d r=%d x=%d y=%d\n", left, right, x, y);
148
149 input_report_key(dev, BTN_LEFT, left);
150 input_report_key(dev, BTN_RIGHT, right);
151
152 input_report_rel(dev, REL_X, x);
153 input_report_rel(dev, REL_Y, y);
154
155 input_sync(dev);
156}
157
158static psmouse_ret_t hgpk_process_byte(struct psmouse *psmouse)
159{
160 struct hgpk_data *priv = psmouse->private;
161
162 if (hgpk_validate_byte(psmouse->packet)) {
163 hgpk_dbg(psmouse, "%s: (%d) %02x %02x %02x\n",
164 __func__, psmouse->pktcnt, psmouse->packet[0],
165 psmouse->packet[1], psmouse->packet[2]);
166 return PSMOUSE_BAD_DATA;
167 }
168
169 if (psmouse->pktcnt >= psmouse->pktsize) {
170 hgpk_process_packet(psmouse);
171 return PSMOUSE_FULL_PACKET;
172 }
173
174 if (priv->recalib_window) {
175 if (time_before(jiffies, priv->recalib_window)) {
176 /*
177 * ugh, got a packet inside our recalibration
178 * window, schedule another recalibration.
179 */
180 hgpk_dbg(psmouse,
181 "packet inside calibration window, "
182 "queueing another recalibration\n");
183 psmouse_queue_work(psmouse, &priv->recalib_wq,
184 msecs_to_jiffies(1000));
185 }
186 priv->recalib_window = 0;
187 }
188
189 return PSMOUSE_GOOD_DATA;
190}
191
192static int hgpk_force_recalibrate(struct psmouse *psmouse)
193{
194 struct ps2dev *ps2dev = &psmouse->ps2dev;
195 struct hgpk_data *priv = psmouse->private;
196
197 /* C-series touchpads added the recalibrate command */
198 if (psmouse->model < HGPK_MODEL_C)
199 return 0;
200
201 /* we don't want to race with the irq handler, nor with resyncs */
202 psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
203
204 /* start by resetting the device */
205 psmouse_reset(psmouse);
206
207 /* send the recalibrate request */
208 if (ps2_command(ps2dev, NULL, 0xf5) ||
209 ps2_command(ps2dev, NULL, 0xf5) ||
210 ps2_command(ps2dev, NULL, 0xe6) ||
211 ps2_command(ps2dev, NULL, 0xf5)) {
212 return -1;
213 }
214
215 /* according to ALPS, 150mS is required for recalibration */
216 msleep(150);
217
218 /* XXX: If a finger is down during this delay, recalibration will
219 * detect capacitance incorrectly. This is a hardware bug, and
220 * we don't have a good way to deal with it. The 2s window stuff
221 * (below) is our best option for now.
222 */
223
224 if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE))
225 return -1;
226
227 psmouse_set_state(psmouse, PSMOUSE_ACTIVATED);
228
229 /* After we recalibrate, we shouldn't get any packets for 2s. If
230 * we do, it's likely that someone's finger was on the touchpad.
231 * If someone's finger *was* on the touchpad, it's probably
232 * miscalibrated. So, we should schedule another recalibration
233 */
234 priv->recalib_window = jiffies + msecs_to_jiffies(2000);
235
236 return 0;
237}
238
239/*
240 * This kills power to the touchpad; according to ALPS, current consumption
241 * goes down to 50uA after running this. To turn power back on, we drive
242 * MS-DAT low.
243 */
244static int hgpk_toggle_power(struct psmouse *psmouse, int enable)
245{
246 struct ps2dev *ps2dev = &psmouse->ps2dev;
247 int timeo;
248
249 /* Added on D-series touchpads */
250 if (psmouse->model < HGPK_MODEL_D)
251 return 0;
252
253 if (enable) {
254 psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
255
256 /*
257 * Sending a byte will drive MS-DAT low; this will wake up
258 * the controller. Once we get an ACK back from it, it
259 * means we can continue with the touchpad re-init. ALPS
260 * tells us that 1s should be long enough, so set that as
261 * the upper bound.
262 */
263 for (timeo = 20; timeo > 0; timeo--) {
264 if (!ps2_sendbyte(&psmouse->ps2dev,
265 PSMOUSE_CMD_DISABLE, 20))
266 break;
267 msleep(50);
268 }
269
270 psmouse_reset(psmouse);
271
272 /* should be all set, enable the touchpad */
273 ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE);
274 psmouse_set_state(psmouse, PSMOUSE_ACTIVATED);
275
276 } else {
277 hgpk_dbg(psmouse, "Powering off touchpad.\n");
278 psmouse_set_state(psmouse, PSMOUSE_IGNORE);
279
280 if (ps2_command(ps2dev, NULL, 0xec) ||
281 ps2_command(ps2dev, NULL, 0xec) ||
282 ps2_command(ps2dev, NULL, 0xea)) {
283 return -1;
284 }
285
286 /* probably won't see an ACK, the touchpad will be off */
287 ps2_sendbyte(&psmouse->ps2dev, 0xec, 20);
288 }
289
290 return 0;
291}
292
293static int hgpk_poll(struct psmouse *psmouse)
294{
295 /* We can't poll, so always return failure. */
296 return -1;
297}
298
299static int hgpk_reconnect(struct psmouse *psmouse)
300{
301 /* During suspend/resume the ps2 rails remain powered. We don't want
302 * to do a reset because it's flush data out of buffers; however,
303 * earlier prototypes (B1) had some brokenness that required a reset. */
304 if (olpc_board_at_least(olpc_board(0xb2)))
305 if (psmouse->ps2dev.serio->dev.power.power_state.event !=
306 PM_EVENT_ON)
307 return 0;
308
309 psmouse_reset(psmouse);
310
311 return 0;
312}
313
314static ssize_t hgpk_show_powered(struct psmouse *psmouse, void *data, char *buf)
315{
316 struct hgpk_data *priv = psmouse->private;
317
318 return sprintf(buf, "%d\n", priv->powered);
319}
320
321static ssize_t hgpk_set_powered(struct psmouse *psmouse, void *data,
322 const char *buf, size_t count)
323{
324 struct hgpk_data *priv = psmouse->private;
325 unsigned long value;
326 int err;
327
328 err = strict_strtoul(buf, 10, &value);
329 if (err || value > 1)
330 return -EINVAL;
331
332 if (value != priv->powered) {
333 /*
334 * hgpk_toggle_power will deal w/ state so
335 * we're not racing w/ irq
336 */
337 err = hgpk_toggle_power(psmouse, value);
338 if (!err)
339 priv->powered = value;
340 }
341
342 return err ? err : count;
343}
344
345__PSMOUSE_DEFINE_ATTR(powered, S_IWUSR | S_IRUGO, NULL,
346 hgpk_show_powered, hgpk_set_powered, 0);
347
348static void hgpk_disconnect(struct psmouse *psmouse)
349{
350 struct hgpk_data *priv = psmouse->private;
351
352 device_remove_file(&psmouse->ps2dev.serio->dev,
353 &psmouse_attr_powered.dattr);
354 psmouse_reset(psmouse);
355 kfree(priv);
356}
357
358static void hgpk_recalib_work(struct work_struct *work)
359{
360 struct delayed_work *w = container_of(work, struct delayed_work, work);
361 struct hgpk_data *priv = container_of(w, struct hgpk_data, recalib_wq);
362 struct psmouse *psmouse = priv->psmouse;
363
364 hgpk_dbg(psmouse, "recalibrating touchpad..\n");
365
366 if (hgpk_force_recalibrate(psmouse))
367 hgpk_err(psmouse, "recalibration failed!\n");
368}
369
370static int hgpk_register(struct psmouse *psmouse)
371{
372 struct input_dev *dev = psmouse->dev;
373 int err;
374
375 /* unset the things that psmouse-base sets which we don't have */
376 __clear_bit(BTN_MIDDLE, dev->keybit);
377
378 /* set the things we do have */
379 __set_bit(EV_KEY, dev->evbit);
380 __set_bit(EV_REL, dev->evbit);
381
382 __set_bit(REL_X, dev->relbit);
383 __set_bit(REL_Y, dev->relbit);
384
385 __set_bit(BTN_LEFT, dev->keybit);
386 __set_bit(BTN_RIGHT, dev->keybit);
387
388 /* register handlers */
389 psmouse->protocol_handler = hgpk_process_byte;
390 psmouse->poll = hgpk_poll;
391 psmouse->disconnect = hgpk_disconnect;
392 psmouse->reconnect = hgpk_reconnect;
393 psmouse->pktsize = 3;
394
395 /* Disable the idle resync. */
396 psmouse->resync_time = 0;
397 /* Reset after a lot of bad bytes. */
398 psmouse->resetafter = 1024;
399
400 err = device_create_file(&psmouse->ps2dev.serio->dev,
401 &psmouse_attr_powered.dattr);
402 if (err)
403 hgpk_err(psmouse, "Failed to create sysfs attribute\n");
404
405 return err;
406}
407
408int hgpk_init(struct psmouse *psmouse)
409{
410 struct hgpk_data *priv;
411 int err = -ENOMEM;
412
413 priv = kzalloc(sizeof(struct hgpk_data), GFP_KERNEL);
414 if (!priv)
415 goto alloc_fail;
416
417 psmouse->private = priv;
418 priv->psmouse = psmouse;
419 priv->powered = 1;
420 INIT_DELAYED_WORK(&priv->recalib_wq, hgpk_recalib_work);
421
422 err = psmouse_reset(psmouse);
423 if (err)
424 goto init_fail;
425
426 err = hgpk_register(psmouse);
427 if (err)
428 goto init_fail;
429
430 return 0;
431
432init_fail:
433 kfree(priv);
434alloc_fail:
435 return err;
436}
437
438static enum hgpk_model_t hgpk_get_model(struct psmouse *psmouse)
439{
440 struct ps2dev *ps2dev = &psmouse->ps2dev;
441 unsigned char param[3];
442
443 /* E7, E7, E7, E9 gets us a 3 byte identifier */
444 if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||
445 ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||
446 ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||
447 ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) {
448 return -EIO;
449 }
450
451 hgpk_dbg(psmouse, "ID: %02x %02x %02x", param[0], param[1], param[2]);
452
453 /* HGPK signature: 0x67, 0x00, 0x<model> */
454 if (param[0] != 0x67 || param[1] != 0x00)
455 return -ENODEV;
456
457 hgpk_info(psmouse, "OLPC touchpad revision 0x%x\n", param[2]);
458
459 return param[2];
460}
461
462int hgpk_detect(struct psmouse *psmouse, int set_properties)
463{
464 int version;
465
466 version = hgpk_get_model(psmouse);
467 if (version < 0)
468 return version;
469
470 if (set_properties) {
471 psmouse->vendor = "ALPS";
472 psmouse->name = "HGPK";
473 psmouse->model = version;
474 }
475
476 return 0;
477}
diff --git a/drivers/input/mouse/hgpk.h b/drivers/input/mouse/hgpk.h
new file mode 100644
index 000000000000..a4b2a96f5f54
--- /dev/null
+++ b/drivers/input/mouse/hgpk.h
@@ -0,0 +1,49 @@
1/*
2 * OLPC HGPK (XO-1) touchpad PS/2 mouse driver
3 */
4
5#ifndef _HGPK_H
6#define _HGPK_H
7
8enum hgpk_model_t {
9 HGPK_MODEL_PREA = 0x0a, /* pre-B1s */
10 HGPK_MODEL_A = 0x14, /* found on B1s, PT disabled in hardware */
11 HGPK_MODEL_B = 0x28, /* B2s, has capacitance issues */
12 HGPK_MODEL_C = 0x3c,
13 HGPK_MODEL_D = 0x50, /* C1, mass production */
14};
15
16struct hgpk_data {
17 struct psmouse *psmouse;
18 int powered;
19 int count, x_tally, y_tally; /* hardware workaround stuff */
20 unsigned long recalib_window;
21 struct delayed_work recalib_wq;
22};
23
24#define hgpk_dbg(psmouse, format, arg...) \
25 dev_dbg(&(psmouse)->ps2dev.serio->dev, format, ## arg)
26#define hgpk_err(psmouse, format, arg...) \
27 dev_err(&(psmouse)->ps2dev.serio->dev, format, ## arg)
28#define hgpk_info(psmouse, format, arg...) \
29 dev_info(&(psmouse)->ps2dev.serio->dev, format, ## arg)
30#define hgpk_warn(psmouse, format, arg...) \
31 dev_warn(&(psmouse)->ps2dev.serio->dev, format, ## arg)
32#define hgpk_notice(psmouse, format, arg...) \
33 dev_notice(&(psmouse)->ps2dev.serio->dev, format, ## arg)
34
35#ifdef CONFIG_MOUSE_PS2_OLPC
36int hgpk_detect(struct psmouse *psmouse, int set_properties);
37int hgpk_init(struct psmouse *psmouse);
38#else
39static inline int hgpk_detect(struct psmouse *psmouse, int set_properties)
40{
41 return -ENODEV;
42}
43static inline int hgpk_init(struct psmouse *psmouse)
44{
45 return -ENODEV;
46}
47#endif
48
49#endif
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c
index 0c5660d28caa..390f1dbb98a4 100644
--- a/drivers/input/mouse/logips2pp.c
+++ b/drivers/input/mouse/logips2pp.c
@@ -157,10 +157,8 @@ static ssize_t ps2pp_attr_show_smartscroll(struct psmouse *psmouse, void *data,
157static ssize_t ps2pp_attr_set_smartscroll(struct psmouse *psmouse, void *data, const char *buf, size_t count) 157static ssize_t ps2pp_attr_set_smartscroll(struct psmouse *psmouse, void *data, const char *buf, size_t count)
158{ 158{
159 unsigned long value; 159 unsigned long value;
160 char *rest;
161 160
162 value = simple_strtoul(buf, &rest, 10); 161 if (strict_strtoul(buf, 10, &value) || value > 1)
163 if (*rest || value > 1)
164 return -EINVAL; 162 return -EINVAL;
165 163
166 ps2pp_set_smartscroll(psmouse, value); 164 ps2pp_set_smartscroll(psmouse, value);
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index f5a6be1d3c46..126e977e199e 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -25,6 +25,7 @@
25#include "synaptics.h" 25#include "synaptics.h"
26#include "logips2pp.h" 26#include "logips2pp.h"
27#include "alps.h" 27#include "alps.h"
28#include "hgpk.h"
28#include "lifebook.h" 29#include "lifebook.h"
29#include "trackpoint.h" 30#include "trackpoint.h"
30#include "touchkit_ps2.h" 31#include "touchkit_ps2.h"
@@ -201,6 +202,12 @@ static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
201 return PSMOUSE_FULL_PACKET; 202 return PSMOUSE_FULL_PACKET;
202} 203}
203 204
205void psmouse_queue_work(struct psmouse *psmouse, struct delayed_work *work,
206 unsigned long delay)
207{
208 queue_delayed_work(kpsmoused_wq, work, delay);
209}
210
204/* 211/*
205 * __psmouse_set_state() sets new psmouse state and resets all flags. 212 * __psmouse_set_state() sets new psmouse state and resets all flags.
206 */ 213 */
@@ -220,7 +227,7 @@ static inline void __psmouse_set_state(struct psmouse *psmouse, enum psmouse_sta
220 * is not a concern. 227 * is not a concern.
221 */ 228 */
222 229
223static void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state) 230void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state)
224{ 231{
225 serio_pause_rx(psmouse->ps2dev.serio); 232 serio_pause_rx(psmouse->ps2dev.serio);
226 __psmouse_set_state(psmouse, new_state); 233 __psmouse_set_state(psmouse, new_state);
@@ -305,7 +312,7 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
305 psmouse->name, psmouse->phys, psmouse->pktcnt); 312 psmouse->name, psmouse->phys, psmouse->pktcnt);
306 psmouse->badbyte = psmouse->packet[0]; 313 psmouse->badbyte = psmouse->packet[0];
307 __psmouse_set_state(psmouse, PSMOUSE_RESYNCING); 314 __psmouse_set_state(psmouse, PSMOUSE_RESYNCING);
308 queue_work(kpsmoused_wq, &psmouse->resync_work); 315 psmouse_queue_work(psmouse, &psmouse->resync_work, 0);
309 goto out; 316 goto out;
310 } 317 }
311 318
@@ -342,7 +349,7 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
342 time_after(jiffies, psmouse->last + psmouse->resync_time * HZ)) { 349 time_after(jiffies, psmouse->last + psmouse->resync_time * HZ)) {
343 psmouse->badbyte = psmouse->packet[0]; 350 psmouse->badbyte = psmouse->packet[0];
344 __psmouse_set_state(psmouse, PSMOUSE_RESYNCING); 351 __psmouse_set_state(psmouse, PSMOUSE_RESYNCING);
345 queue_work(kpsmoused_wq, &psmouse->resync_work); 352 psmouse_queue_work(psmouse, &psmouse->resync_work, 0);
346 goto out; 353 goto out;
347 } 354 }
348 355
@@ -630,8 +637,20 @@ static int psmouse_extensions(struct psmouse *psmouse,
630 } 637 }
631 } 638 }
632 639
633 if (max_proto > PSMOUSE_IMEX) { 640/*
641 * Try OLPC HGPK touchpad.
642 */
643 if (max_proto > PSMOUSE_IMEX &&
644 hgpk_detect(psmouse, set_properties) == 0) {
645 if (!set_properties || hgpk_init(psmouse) == 0)
646 return PSMOUSE_HGPK;
647/*
648 * Init failed, try basic relative protocols
649 */
650 max_proto = PSMOUSE_IMEX;
651 }
634 652
653 if (max_proto > PSMOUSE_IMEX) {
635 if (genius_detect(psmouse, set_properties) == 0) 654 if (genius_detect(psmouse, set_properties) == 0)
636 return PSMOUSE_GENPS; 655 return PSMOUSE_GENPS;
637 656
@@ -762,6 +781,14 @@ static const struct psmouse_protocol psmouse_protocols[] = {
762 .detect = touchkit_ps2_detect, 781 .detect = touchkit_ps2_detect,
763 }, 782 },
764#endif 783#endif
784#ifdef CONFIG_MOUSE_PS2_OLPC
785 {
786 .type = PSMOUSE_HGPK,
787 .name = "OLPC HGPK",
788 .alias = "hgpk",
789 .detect = hgpk_detect,
790 },
791#endif
765 { 792 {
766 .type = PSMOUSE_CORTRON, 793 .type = PSMOUSE_CORTRON,
767 .name = "CortronPS/2", 794 .name = "CortronPS/2",
@@ -935,7 +962,7 @@ static int psmouse_poll(struct psmouse *psmouse)
935static void psmouse_resync(struct work_struct *work) 962static void psmouse_resync(struct work_struct *work)
936{ 963{
937 struct psmouse *parent = NULL, *psmouse = 964 struct psmouse *parent = NULL, *psmouse =
938 container_of(work, struct psmouse, resync_work); 965 container_of(work, struct psmouse, resync_work.work);
939 struct serio *serio = psmouse->ps2dev.serio; 966 struct serio *serio = psmouse->ps2dev.serio;
940 psmouse_ret_t rc = PSMOUSE_GOOD_DATA; 967 psmouse_ret_t rc = PSMOUSE_GOOD_DATA;
941 int failed = 0, enabled = 0; 968 int failed = 0, enabled = 0;
@@ -1194,7 +1221,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
1194 goto err_free; 1221 goto err_free;
1195 1222
1196 ps2_init(&psmouse->ps2dev, serio); 1223 ps2_init(&psmouse->ps2dev, serio);
1197 INIT_WORK(&psmouse->resync_work, psmouse_resync); 1224 INIT_DELAYED_WORK(&psmouse->resync_work, psmouse_resync);
1198 psmouse->dev = input_dev; 1225 psmouse->dev = input_dev;
1199 snprintf(psmouse->phys, sizeof(psmouse->phys), "%s/input0", serio->phys); 1226 snprintf(psmouse->phys, sizeof(psmouse->phys), "%s/input0", serio->phys);
1200 1227
@@ -1395,25 +1422,29 @@ ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *dev
1395 1422
1396 psmouse = serio_get_drvdata(serio); 1423 psmouse = serio_get_drvdata(serio);
1397 1424
1398 if (psmouse->state == PSMOUSE_IGNORE) { 1425 if (attr->protect) {
1399 retval = -ENODEV; 1426 if (psmouse->state == PSMOUSE_IGNORE) {
1400 goto out_unlock; 1427 retval = -ENODEV;
1401 } 1428 goto out_unlock;
1429 }
1402 1430
1403 if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { 1431 if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
1404 parent = serio_get_drvdata(serio->parent); 1432 parent = serio_get_drvdata(serio->parent);
1405 psmouse_deactivate(parent); 1433 psmouse_deactivate(parent);
1406 } 1434 }
1407 1435
1408 psmouse_deactivate(psmouse); 1436 psmouse_deactivate(psmouse);
1437 }
1409 1438
1410 retval = attr->set(psmouse, attr->data, buf, count); 1439 retval = attr->set(psmouse, attr->data, buf, count);
1411 1440
1412 if (retval != -ENODEV) 1441 if (attr->protect) {
1413 psmouse_activate(psmouse); 1442 if (retval != -ENODEV)
1443 psmouse_activate(psmouse);
1414 1444
1415 if (parent) 1445 if (parent)
1416 psmouse_activate(parent); 1446 psmouse_activate(parent);
1447 }
1417 1448
1418 out_unlock: 1449 out_unlock:
1419 mutex_unlock(&psmouse_mutex); 1450 mutex_unlock(&psmouse_mutex);
@@ -1433,10 +1464,8 @@ static ssize_t psmouse_set_int_attr(struct psmouse *psmouse, void *offset, const
1433{ 1464{
1434 unsigned int *field = (unsigned int *)((char *)psmouse + (size_t)offset); 1465 unsigned int *field = (unsigned int *)((char *)psmouse + (size_t)offset);
1435 unsigned long value; 1466 unsigned long value;
1436 char *rest;
1437 1467
1438 value = simple_strtoul(buf, &rest, 10); 1468 if (strict_strtoul(buf, 10, &value))
1439 if (*rest)
1440 return -EINVAL; 1469 return -EINVAL;
1441 1470
1442 if ((unsigned int)value != value) 1471 if ((unsigned int)value != value)
@@ -1549,10 +1578,8 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co
1549static ssize_t psmouse_attr_set_rate(struct psmouse *psmouse, void *data, const char *buf, size_t count) 1578static ssize_t psmouse_attr_set_rate(struct psmouse *psmouse, void *data, const char *buf, size_t count)
1550{ 1579{
1551 unsigned long value; 1580 unsigned long value;
1552 char *rest;
1553 1581
1554 value = simple_strtoul(buf, &rest, 10); 1582 if (strict_strtoul(buf, 10, &value))
1555 if (*rest)
1556 return -EINVAL; 1583 return -EINVAL;
1557 1584
1558 psmouse->set_rate(psmouse, value); 1585 psmouse->set_rate(psmouse, value);
@@ -1562,10 +1589,8 @@ static ssize_t psmouse_attr_set_rate(struct psmouse *psmouse, void *data, const
1562static ssize_t psmouse_attr_set_resolution(struct psmouse *psmouse, void *data, const char *buf, size_t count) 1589static ssize_t psmouse_attr_set_resolution(struct psmouse *psmouse, void *data, const char *buf, size_t count)
1563{ 1590{
1564 unsigned long value; 1591 unsigned long value;
1565 char *rest;
1566 1592
1567 value = simple_strtoul(buf, &rest, 10); 1593 if (strict_strtoul(buf, 10, &value))
1568 if (*rest)
1569 return -EINVAL; 1594 return -EINVAL;
1570 1595
1571 psmouse->set_resolution(psmouse, value); 1596 psmouse->set_resolution(psmouse, value);
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
index 1317bdd8cc7c..8b608a1cdd12 100644
--- a/drivers/input/mouse/psmouse.h
+++ b/drivers/input/mouse/psmouse.h
@@ -39,7 +39,7 @@ struct psmouse {
39 void *private; 39 void *private;
40 struct input_dev *dev; 40 struct input_dev *dev;
41 struct ps2dev ps2dev; 41 struct ps2dev ps2dev;
42 struct work_struct resync_work; 42 struct delayed_work resync_work;
43 char *vendor; 43 char *vendor;
44 char *name; 44 char *name;
45 unsigned char packet[8]; 45 unsigned char packet[8];
@@ -89,20 +89,24 @@ enum psmouse_type {
89 PSMOUSE_TRACKPOINT, 89 PSMOUSE_TRACKPOINT,
90 PSMOUSE_TOUCHKIT_PS2, 90 PSMOUSE_TOUCHKIT_PS2,
91 PSMOUSE_CORTRON, 91 PSMOUSE_CORTRON,
92 PSMOUSE_HGPK,
92 PSMOUSE_AUTO /* This one should always be last */ 93 PSMOUSE_AUTO /* This one should always be last */
93}; 94};
94 95
96void psmouse_queue_work(struct psmouse *psmouse, struct delayed_work *work,
97 unsigned long delay);
95int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command); 98int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command);
96int psmouse_reset(struct psmouse *psmouse); 99int psmouse_reset(struct psmouse *psmouse);
100void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state);
97void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution); 101void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution);
98 102
99
100struct psmouse_attribute { 103struct psmouse_attribute {
101 struct device_attribute dattr; 104 struct device_attribute dattr;
102 void *data; 105 void *data;
103 ssize_t (*show)(struct psmouse *psmouse, void *data, char *buf); 106 ssize_t (*show)(struct psmouse *psmouse, void *data, char *buf);
104 ssize_t (*set)(struct psmouse *psmouse, void *data, 107 ssize_t (*set)(struct psmouse *psmouse, void *data,
105 const char *buf, size_t count); 108 const char *buf, size_t count);
109 int protect;
106}; 110};
107#define to_psmouse_attr(a) container_of((a), struct psmouse_attribute, dattr) 111#define to_psmouse_attr(a) container_of((a), struct psmouse_attribute, dattr)
108 112
@@ -111,7 +115,7 @@ ssize_t psmouse_attr_show_helper(struct device *dev, struct device_attribute *at
111ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *attr, 115ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *attr,
112 const char *buf, size_t count); 116 const char *buf, size_t count);
113 117
114#define PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set) \ 118#define __PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set, _protect) \
115static ssize_t _show(struct psmouse *, void *data, char *); \ 119static ssize_t _show(struct psmouse *, void *data, char *); \
116static ssize_t _set(struct psmouse *, void *data, const char *, size_t); \ 120static ssize_t _set(struct psmouse *, void *data, const char *, size_t); \
117static struct psmouse_attribute psmouse_attr_##_name = { \ 121static struct psmouse_attribute psmouse_attr_##_name = { \
@@ -126,6 +130,10 @@ static struct psmouse_attribute psmouse_attr_##_name = { \
126 .data = _data, \ 130 .data = _data, \
127 .show = _show, \ 131 .show = _show, \
128 .set = _set, \ 132 .set = _set, \
133 .protect = _protect, \
129} 134}
130 135
136#define PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set) \
137 __PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set, 1)
138
131#endif /* _PSMOUSE_H */ 139#endif /* _PSMOUSE_H */
diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c
index 26b845fc186a..e68c814c4361 100644
--- a/drivers/input/mouse/trackpoint.c
+++ b/drivers/input/mouse/trackpoint.c
@@ -89,10 +89,8 @@ static ssize_t trackpoint_set_int_attr(struct psmouse *psmouse, void *data,
89 struct trackpoint_attr_data *attr = data; 89 struct trackpoint_attr_data *attr = data;
90 unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset); 90 unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset);
91 unsigned long value; 91 unsigned long value;
92 char *rest;
93 92
94 value = simple_strtoul(buf, &rest, 10); 93 if (strict_strtoul(buf, 10, &value) || value > 255)
95 if (*rest || value > 255)
96 return -EINVAL; 94 return -EINVAL;
97 95
98 *field = value; 96 *field = value;
@@ -117,10 +115,8 @@ static ssize_t trackpoint_set_bit_attr(struct psmouse *psmouse, void *data,
117 struct trackpoint_attr_data *attr = data; 115 struct trackpoint_attr_data *attr = data;
118 unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset); 116 unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset);
119 unsigned long value; 117 unsigned long value;
120 char *rest;
121 118
122 value = simple_strtoul(buf, &rest, 10); 119 if (strict_strtoul(buf, 10, &value) || value > 1)
123 if (*rest || value > 1)
124 return -EINVAL; 120 return -EINVAL;
125 121
126 if (attr->inverted) 122 if (attr->inverted)
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index 5aafe24984c5..a321aea2c7b5 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -322,6 +322,13 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
322 DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"), 322 DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"),
323 }, 323 },
324 }, 324 },
325 {
326 .ident = "IBM 2656",
327 .matches = {
328 DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
329 DMI_MATCH(DMI_PRODUCT_NAME, "2656"),
330 },
331 },
325 { } 332 { }
326}; 333};
327 334
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c
index c9397c8ee97e..470770c09260 100644
--- a/drivers/input/serio/serio_raw.c
+++ b/drivers/input/serio/serio_raw.c
@@ -373,6 +373,12 @@ static struct serio_device_id serio_raw_serio_ids[] = {
373 .id = SERIO_ANY, 373 .id = SERIO_ANY,
374 .extra = SERIO_ANY, 374 .extra = SERIO_ANY,
375 }, 375 },
376 {
377 .type = SERIO_8042_XL,
378 .proto = SERIO_ANY,
379 .id = SERIO_ANY,
380 .extra = SERIO_ANY,
381 },
376 { 0 } 382 { 0 }
377}; 383};
378 384
diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c
index 8f037a1d44a6..e53c838f1866 100644
--- a/drivers/input/tablet/aiptek.c
+++ b/drivers/input/tablet/aiptek.c
@@ -1202,16 +1202,22 @@ static ssize_t
1202store_tabletXtilt(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 1202store_tabletXtilt(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
1203{ 1203{
1204 struct aiptek *aiptek = dev_get_drvdata(dev); 1204 struct aiptek *aiptek = dev_get_drvdata(dev);
1205 int x; 1205 long x;
1206
1207 if (strict_strtol(buf, 10, &x)) {
1208 size_t len = buf[count - 1] == '\n' ? count - 1 : count;
1209
1210 if (strncmp(buf, "disable", len))
1211 return -EINVAL;
1206 1212
1207 if (strcmp(buf, "disable") == 0) {
1208 aiptek->newSetting.xTilt = AIPTEK_TILT_DISABLE; 1213 aiptek->newSetting.xTilt = AIPTEK_TILT_DISABLE;
1209 } else { 1214 } else {
1210 x = (int)simple_strtol(buf, NULL, 10); 1215 if (x < AIPTEK_TILT_MIN || x > AIPTEK_TILT_MAX)
1211 if (x >= AIPTEK_TILT_MIN && x <= AIPTEK_TILT_MAX) { 1216 return -EINVAL;
1212 aiptek->newSetting.xTilt = x; 1217
1213 } 1218 aiptek->newSetting.xTilt = x;
1214 } 1219 }
1220
1215 return count; 1221 return count;
1216} 1222}
1217 1223
@@ -1238,16 +1244,22 @@ static ssize_t
1238store_tabletYtilt(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 1244store_tabletYtilt(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
1239{ 1245{
1240 struct aiptek *aiptek = dev_get_drvdata(dev); 1246 struct aiptek *aiptek = dev_get_drvdata(dev);
1241 int y; 1247 long y;
1248
1249 if (strict_strtol(buf, 10, &y)) {
1250 size_t len = buf[count - 1] == '\n' ? count - 1 : count;
1251
1252 if (strncmp(buf, "disable", len))
1253 return -EINVAL;
1242 1254
1243 if (strcmp(buf, "disable") == 0) {
1244 aiptek->newSetting.yTilt = AIPTEK_TILT_DISABLE; 1255 aiptek->newSetting.yTilt = AIPTEK_TILT_DISABLE;
1245 } else { 1256 } else {
1246 y = (int)simple_strtol(buf, NULL, 10); 1257 if (y < AIPTEK_TILT_MIN || y > AIPTEK_TILT_MAX)
1247 if (y >= AIPTEK_TILT_MIN && y <= AIPTEK_TILT_MAX) { 1258 return -EINVAL;
1248 aiptek->newSetting.yTilt = y; 1259
1249 } 1260 aiptek->newSetting.yTilt = y;
1250 } 1261 }
1262
1251 return count; 1263 return count;
1252} 1264}
1253 1265
@@ -1269,8 +1281,12 @@ static ssize_t
1269store_tabletJitterDelay(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 1281store_tabletJitterDelay(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
1270{ 1282{
1271 struct aiptek *aiptek = dev_get_drvdata(dev); 1283 struct aiptek *aiptek = dev_get_drvdata(dev);
1284 long j;
1285
1286 if (strict_strtol(buf, 10, &j))
1287 return -EINVAL;
1272 1288
1273 aiptek->newSetting.jitterDelay = (int)simple_strtol(buf, NULL, 10); 1289 aiptek->newSetting.jitterDelay = (int)j;
1274 return count; 1290 return count;
1275} 1291}
1276 1292
@@ -1294,8 +1310,12 @@ static ssize_t
1294store_tabletProgrammableDelay(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 1310store_tabletProgrammableDelay(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
1295{ 1311{
1296 struct aiptek *aiptek = dev_get_drvdata(dev); 1312 struct aiptek *aiptek = dev_get_drvdata(dev);
1313 long d;
1297 1314
1298 aiptek->newSetting.programmableDelay = (int)simple_strtol(buf, NULL, 10); 1315 if (strict_strtol(buf, 10, &d))
1316 return -EINVAL;
1317
1318 aiptek->newSetting.programmableDelay = (int)d;
1299 return count; 1319 return count;
1300} 1320}
1301 1321
@@ -1541,8 +1561,11 @@ static ssize_t
1541store_tabletWheel(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 1561store_tabletWheel(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
1542{ 1562{
1543 struct aiptek *aiptek = dev_get_drvdata(dev); 1563 struct aiptek *aiptek = dev_get_drvdata(dev);
1564 long w;
1565
1566 if (strict_strtol(buf, 10, &w)) return -EINVAL;
1544 1567
1545 aiptek->newSetting.wheel = (int)simple_strtol(buf, NULL, 10); 1568 aiptek->newSetting.wheel = (int)w;
1546 return count; 1569 return count;
1547} 1570}
1548 1571
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index 8583c766d565..b9b7fc6ff1eb 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -69,6 +69,17 @@ struct ts_event {
69 int ignore; 69 int ignore;
70}; 70};
71 71
72/*
73 * We allocate this separately to avoid cache line sharing issues when
74 * driver is used with DMA-based SPI controllers (like atmel_spi) on
75 * systems where main memory is not DMA-coherent (most non-x86 boards).
76 */
77struct ads7846_packet {
78 u8 read_x, read_y, read_z1, read_z2, pwrdown;
79 u16 dummy; /* for the pwrdown read */
80 struct ts_event tc;
81};
82
72struct ads7846 { 83struct ads7846 {
73 struct input_dev *input; 84 struct input_dev *input;
74 char phys[32]; 85 char phys[32];
@@ -86,9 +97,7 @@ struct ads7846 {
86 u16 x_plate_ohms; 97 u16 x_plate_ohms;
87 u16 pressure_max; 98 u16 pressure_max;
88 99
89 u8 read_x, read_y, read_z1, read_z2, pwrdown; 100 struct ads7846_packet *packet;
90 u16 dummy; /* for the pwrdown read */
91 struct ts_event tc;
92 101
93 struct spi_transfer xfer[18]; 102 struct spi_transfer xfer[18];
94 struct spi_message msg[5]; 103 struct spi_message msg[5];
@@ -463,10 +472,11 @@ static ssize_t ads7846_disable_store(struct device *dev,
463 const char *buf, size_t count) 472 const char *buf, size_t count)
464{ 473{
465 struct ads7846 *ts = dev_get_drvdata(dev); 474 struct ads7846 *ts = dev_get_drvdata(dev);
466 char *endp; 475 long i;
467 int i; 476
477 if (strict_strtoul(buf, 10, &i))
478 return -EINVAL;
468 479
469 i = simple_strtoul(buf, &endp, 10);
470 spin_lock_irq(&ts->lock); 480 spin_lock_irq(&ts->lock);
471 481
472 if (i) 482 if (i)
@@ -512,16 +522,17 @@ static int get_pendown_state(struct ads7846 *ts)
512static void ads7846_rx(void *ads) 522static void ads7846_rx(void *ads)
513{ 523{
514 struct ads7846 *ts = ads; 524 struct ads7846 *ts = ads;
525 struct ads7846_packet *packet = ts->packet;
515 unsigned Rt; 526 unsigned Rt;
516 u16 x, y, z1, z2; 527 u16 x, y, z1, z2;
517 528
518 /* ads7846_rx_val() did in-place conversion (including byteswap) from 529 /* ads7846_rx_val() did in-place conversion (including byteswap) from
519 * on-the-wire format as part of debouncing to get stable readings. 530 * on-the-wire format as part of debouncing to get stable readings.
520 */ 531 */
521 x = ts->tc.x; 532 x = packet->tc.x;
522 y = ts->tc.y; 533 y = packet->tc.y;
523 z1 = ts->tc.z1; 534 z1 = packet->tc.z1;
524 z2 = ts->tc.z2; 535 z2 = packet->tc.z2;
525 536
526 /* range filtering */ 537 /* range filtering */
527 if (x == MAX_12BIT) 538 if (x == MAX_12BIT)
@@ -545,10 +556,10 @@ static void ads7846_rx(void *ads)
545 * the maximum. Don't report it to user space, repeat at least 556 * the maximum. Don't report it to user space, repeat at least
546 * once more the measurement 557 * once more the measurement
547 */ 558 */
548 if (ts->tc.ignore || Rt > ts->pressure_max) { 559 if (packet->tc.ignore || Rt > ts->pressure_max) {
549#ifdef VERBOSE 560#ifdef VERBOSE
550 pr_debug("%s: ignored %d pressure %d\n", 561 pr_debug("%s: ignored %d pressure %d\n",
551 ts->spi->dev.bus_id, ts->tc.ignore, Rt); 562 ts->spi->dev.bus_id, packet->tc.ignore, Rt);
552#endif 563#endif
553 hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), 564 hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD),
554 HRTIMER_MODE_REL); 565 HRTIMER_MODE_REL);
@@ -641,6 +652,7 @@ static int ads7846_no_filter(void *ads, int data_idx, int *val)
641static void ads7846_rx_val(void *ads) 652static void ads7846_rx_val(void *ads)
642{ 653{
643 struct ads7846 *ts = ads; 654 struct ads7846 *ts = ads;
655 struct ads7846_packet *packet = ts->packet;
644 struct spi_message *m; 656 struct spi_message *m;
645 struct spi_transfer *t; 657 struct spi_transfer *t;
646 int val; 658 int val;
@@ -660,7 +672,7 @@ static void ads7846_rx_val(void *ads)
660 case ADS7846_FILTER_REPEAT: 672 case ADS7846_FILTER_REPEAT:
661 break; 673 break;
662 case ADS7846_FILTER_IGNORE: 674 case ADS7846_FILTER_IGNORE:
663 ts->tc.ignore = 1; 675 packet->tc.ignore = 1;
664 /* Last message will contain ads7846_rx() as the 676 /* Last message will contain ads7846_rx() as the
665 * completion function. 677 * completion function.
666 */ 678 */
@@ -668,7 +680,7 @@ static void ads7846_rx_val(void *ads)
668 break; 680 break;
669 case ADS7846_FILTER_OK: 681 case ADS7846_FILTER_OK:
670 *(u16 *)t->rx_buf = val; 682 *(u16 *)t->rx_buf = val;
671 ts->tc.ignore = 0; 683 packet->tc.ignore = 0;
672 m = &ts->msg[++ts->msg_idx]; 684 m = &ts->msg[++ts->msg_idx];
673 break; 685 break;
674 default: 686 default:
@@ -773,7 +785,6 @@ static void ads7846_disable(struct ads7846 *ts)
773 /* we know the chip's in lowpower mode since we always 785 /* we know the chip's in lowpower mode since we always
774 * leave it that way after every request 786 * leave it that way after every request
775 */ 787 */
776
777} 788}
778 789
779/* Must be called with ts->lock held */ 790/* Must be called with ts->lock held */
@@ -849,6 +860,7 @@ static int __devinit setup_pendown(struct spi_device *spi, struct ads7846 *ts)
849static int __devinit ads7846_probe(struct spi_device *spi) 860static int __devinit ads7846_probe(struct spi_device *spi)
850{ 861{
851 struct ads7846 *ts; 862 struct ads7846 *ts;
863 struct ads7846_packet *packet;
852 struct input_dev *input_dev; 864 struct input_dev *input_dev;
853 struct ads7846_platform_data *pdata = spi->dev.platform_data; 865 struct ads7846_platform_data *pdata = spi->dev.platform_data;
854 struct spi_message *m; 866 struct spi_message *m;
@@ -884,14 +896,16 @@ static int __devinit ads7846_probe(struct spi_device *spi)
884 return err; 896 return err;
885 897
886 ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL); 898 ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL);
899 packet = kzalloc(sizeof(struct ads7846_packet), GFP_KERNEL);
887 input_dev = input_allocate_device(); 900 input_dev = input_allocate_device();
888 if (!ts || !input_dev) { 901 if (!ts || !packet || !input_dev) {
889 err = -ENOMEM; 902 err = -ENOMEM;
890 goto err_free_mem; 903 goto err_free_mem;
891 } 904 }
892 905
893 dev_set_drvdata(&spi->dev, ts); 906 dev_set_drvdata(&spi->dev, ts);
894 907
908 ts->packet = packet;
895 ts->spi = spi; 909 ts->spi = spi;
896 ts->input = input_dev; 910 ts->input = input_dev;
897 ts->vref_mv = pdata->vref_mv; 911 ts->vref_mv = pdata->vref_mv;
@@ -963,13 +977,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
963 spi_message_init(m); 977 spi_message_init(m);
964 978
965 /* y- still on; turn on only y+ (and ADC) */ 979 /* y- still on; turn on only y+ (and ADC) */
966 ts->read_y = READ_Y(vref); 980 packet->read_y = READ_Y(vref);
967 x->tx_buf = &ts->read_y; 981 x->tx_buf = &packet->read_y;
968 x->len = 1; 982 x->len = 1;
969 spi_message_add_tail(x, m); 983 spi_message_add_tail(x, m);
970 984
971 x++; 985 x++;
972 x->rx_buf = &ts->tc.y; 986 x->rx_buf = &packet->tc.y;
973 x->len = 2; 987 x->len = 2;
974 spi_message_add_tail(x, m); 988 spi_message_add_tail(x, m);
975 989
@@ -981,12 +995,12 @@ static int __devinit ads7846_probe(struct spi_device *spi)
981 x->delay_usecs = pdata->settle_delay_usecs; 995 x->delay_usecs = pdata->settle_delay_usecs;
982 996
983 x++; 997 x++;
984 x->tx_buf = &ts->read_y; 998 x->tx_buf = &packet->read_y;
985 x->len = 1; 999 x->len = 1;
986 spi_message_add_tail(x, m); 1000 spi_message_add_tail(x, m);
987 1001
988 x++; 1002 x++;
989 x->rx_buf = &ts->tc.y; 1003 x->rx_buf = &packet->tc.y;
990 x->len = 2; 1004 x->len = 2;
991 spi_message_add_tail(x, m); 1005 spi_message_add_tail(x, m);
992 } 1006 }
@@ -999,13 +1013,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
999 1013
1000 /* turn y- off, x+ on, then leave in lowpower */ 1014 /* turn y- off, x+ on, then leave in lowpower */
1001 x++; 1015 x++;
1002 ts->read_x = READ_X(vref); 1016 packet->read_x = READ_X(vref);
1003 x->tx_buf = &ts->read_x; 1017 x->tx_buf = &packet->read_x;
1004 x->len = 1; 1018 x->len = 1;
1005 spi_message_add_tail(x, m); 1019 spi_message_add_tail(x, m);
1006 1020
1007 x++; 1021 x++;
1008 x->rx_buf = &ts->tc.x; 1022 x->rx_buf = &packet->tc.x;
1009 x->len = 2; 1023 x->len = 2;
1010 spi_message_add_tail(x, m); 1024 spi_message_add_tail(x, m);
1011 1025
@@ -1014,12 +1028,12 @@ static int __devinit ads7846_probe(struct spi_device *spi)
1014 x->delay_usecs = pdata->settle_delay_usecs; 1028 x->delay_usecs = pdata->settle_delay_usecs;
1015 1029
1016 x++; 1030 x++;
1017 x->tx_buf = &ts->read_x; 1031 x->tx_buf = &packet->read_x;
1018 x->len = 1; 1032 x->len = 1;
1019 spi_message_add_tail(x, m); 1033 spi_message_add_tail(x, m);
1020 1034
1021 x++; 1035 x++;
1022 x->rx_buf = &ts->tc.x; 1036 x->rx_buf = &packet->tc.x;
1023 x->len = 2; 1037 x->len = 2;
1024 spi_message_add_tail(x, m); 1038 spi_message_add_tail(x, m);
1025 } 1039 }
@@ -1033,13 +1047,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
1033 spi_message_init(m); 1047 spi_message_init(m);
1034 1048
1035 x++; 1049 x++;
1036 ts->read_z1 = READ_Z1(vref); 1050 packet->read_z1 = READ_Z1(vref);
1037 x->tx_buf = &ts->read_z1; 1051 x->tx_buf = &packet->read_z1;
1038 x->len = 1; 1052 x->len = 1;
1039 spi_message_add_tail(x, m); 1053 spi_message_add_tail(x, m);
1040 1054
1041 x++; 1055 x++;
1042 x->rx_buf = &ts->tc.z1; 1056 x->rx_buf = &packet->tc.z1;
1043 x->len = 2; 1057 x->len = 2;
1044 spi_message_add_tail(x, m); 1058 spi_message_add_tail(x, m);
1045 1059
@@ -1048,12 +1062,12 @@ static int __devinit ads7846_probe(struct spi_device *spi)
1048 x->delay_usecs = pdata->settle_delay_usecs; 1062 x->delay_usecs = pdata->settle_delay_usecs;
1049 1063
1050 x++; 1064 x++;
1051 x->tx_buf = &ts->read_z1; 1065 x->tx_buf = &packet->read_z1;
1052 x->len = 1; 1066 x->len = 1;
1053 spi_message_add_tail(x, m); 1067 spi_message_add_tail(x, m);
1054 1068
1055 x++; 1069 x++;
1056 x->rx_buf = &ts->tc.z1; 1070 x->rx_buf = &packet->tc.z1;
1057 x->len = 2; 1071 x->len = 2;
1058 spi_message_add_tail(x, m); 1072 spi_message_add_tail(x, m);
1059 } 1073 }
@@ -1065,13 +1079,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
1065 spi_message_init(m); 1079 spi_message_init(m);
1066 1080
1067 x++; 1081 x++;
1068 ts->read_z2 = READ_Z2(vref); 1082 packet->read_z2 = READ_Z2(vref);
1069 x->tx_buf = &ts->read_z2; 1083 x->tx_buf = &packet->read_z2;
1070 x->len = 1; 1084 x->len = 1;
1071 spi_message_add_tail(x, m); 1085 spi_message_add_tail(x, m);
1072 1086
1073 x++; 1087 x++;
1074 x->rx_buf = &ts->tc.z2; 1088 x->rx_buf = &packet->tc.z2;
1075 x->len = 2; 1089 x->len = 2;
1076 spi_message_add_tail(x, m); 1090 spi_message_add_tail(x, m);
1077 1091
@@ -1080,12 +1094,12 @@ static int __devinit ads7846_probe(struct spi_device *spi)
1080 x->delay_usecs = pdata->settle_delay_usecs; 1094 x->delay_usecs = pdata->settle_delay_usecs;
1081 1095
1082 x++; 1096 x++;
1083 x->tx_buf = &ts->read_z2; 1097 x->tx_buf = &packet->read_z2;
1084 x->len = 1; 1098 x->len = 1;
1085 spi_message_add_tail(x, m); 1099 spi_message_add_tail(x, m);
1086 1100
1087 x++; 1101 x++;
1088 x->rx_buf = &ts->tc.z2; 1102 x->rx_buf = &packet->tc.z2;
1089 x->len = 2; 1103 x->len = 2;
1090 spi_message_add_tail(x, m); 1104 spi_message_add_tail(x, m);
1091 } 1105 }
@@ -1099,13 +1113,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
1099 spi_message_init(m); 1113 spi_message_init(m);
1100 1114
1101 x++; 1115 x++;
1102 ts->pwrdown = PWRDOWN; 1116 packet->pwrdown = PWRDOWN;
1103 x->tx_buf = &ts->pwrdown; 1117 x->tx_buf = &packet->pwrdown;
1104 x->len = 1; 1118 x->len = 1;
1105 spi_message_add_tail(x, m); 1119 spi_message_add_tail(x, m);
1106 1120
1107 x++; 1121 x++;
1108 x->rx_buf = &ts->dummy; 1122 x->rx_buf = &packet->dummy;
1109 x->len = 2; 1123 x->len = 2;
1110 CS_CHANGE(*x); 1124 CS_CHANGE(*x);
1111 spi_message_add_tail(x, m); 1125 spi_message_add_tail(x, m);
@@ -1158,6 +1172,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
1158 ts->filter_cleanup(ts->filter_data); 1172 ts->filter_cleanup(ts->filter_data);
1159 err_free_mem: 1173 err_free_mem:
1160 input_free_device(input_dev); 1174 input_free_device(input_dev);
1175 kfree(packet);
1161 kfree(ts); 1176 kfree(ts);
1162 return err; 1177 return err;
1163} 1178}
@@ -1183,6 +1198,7 @@ static int __devexit ads7846_remove(struct spi_device *spi)
1183 if (ts->filter_cleanup) 1198 if (ts->filter_cleanup)
1184 ts->filter_cleanup(ts->filter_data); 1199 ts->filter_cleanup(ts->filter_data);
1185 1200
1201 kfree(ts->packet);
1186 kfree(ts); 1202 kfree(ts);
1187 1203
1188 dev_dbg(&spi->dev, "unregistered touchscreen\n"); 1204 dev_dbg(&spi->dev, "unregistered touchscreen\n");
diff --git a/drivers/input/touchscreen/atmel_tsadcc.c b/drivers/input/touchscreen/atmel_tsadcc.c
index eee126b19e8b..a89a6a8f05e6 100644
--- a/drivers/input/touchscreen/atmel_tsadcc.c
+++ b/drivers/input/touchscreen/atmel_tsadcc.c
@@ -91,6 +91,9 @@ struct atmel_tsadcc {
91 char phys[32]; 91 char phys[32];
92 struct clk *clk; 92 struct clk *clk;
93 int irq; 93 int irq;
94 unsigned int prev_absx;
95 unsigned int prev_absy;
96 unsigned char bufferedmeasure;
94}; 97};
95 98
96static void __iomem *tsc_base; 99static void __iomem *tsc_base;
@@ -100,10 +103,9 @@ static void __iomem *tsc_base;
100 103
101static irqreturn_t atmel_tsadcc_interrupt(int irq, void *dev) 104static irqreturn_t atmel_tsadcc_interrupt(int irq, void *dev)
102{ 105{
103 struct input_dev *input_dev = ((struct atmel_tsadcc *)dev)->input; 106 struct atmel_tsadcc *ts_dev = (struct atmel_tsadcc *)dev;
107 struct input_dev *input_dev = ts_dev->input;
104 108
105 unsigned int absx;
106 unsigned int absy;
107 unsigned int status; 109 unsigned int status;
108 unsigned int reg; 110 unsigned int reg;
109 111
@@ -121,6 +123,7 @@ static irqreturn_t atmel_tsadcc_interrupt(int irq, void *dev)
121 atmel_tsadcc_write(ATMEL_TSADCC_IER, ATMEL_TSADCC_PENCNT); 123 atmel_tsadcc_write(ATMEL_TSADCC_IER, ATMEL_TSADCC_PENCNT);
122 124
123 input_report_key(input_dev, BTN_TOUCH, 0); 125 input_report_key(input_dev, BTN_TOUCH, 0);
126 ts_dev->bufferedmeasure = 0;
124 input_sync(input_dev); 127 input_sync(input_dev);
125 128
126 } else if (status & ATMEL_TSADCC_PENCNT) { 129 } else if (status & ATMEL_TSADCC_PENCNT) {
@@ -138,16 +141,23 @@ static irqreturn_t atmel_tsadcc_interrupt(int irq, void *dev)
138 } else if (status & ATMEL_TSADCC_EOC(3)) { 141 } else if (status & ATMEL_TSADCC_EOC(3)) {
139 /* Conversion finished */ 142 /* Conversion finished */
140 143
141 absx = atmel_tsadcc_read(ATMEL_TSADCC_CDR3) << 10; 144 if (ts_dev->bufferedmeasure) {
142 absx /= atmel_tsadcc_read(ATMEL_TSADCC_CDR2); 145 /* Last measurement is always discarded, since it can
143 146 * be erroneous.
144 absy = atmel_tsadcc_read(ATMEL_TSADCC_CDR1) << 10; 147 * Always report previous measurement */
145 absy /= atmel_tsadcc_read(ATMEL_TSADCC_CDR0); 148 input_report_abs(input_dev, ABS_X, ts_dev->prev_absx);
146 149 input_report_abs(input_dev, ABS_Y, ts_dev->prev_absy);
147 input_report_abs(input_dev, ABS_X, absx); 150 input_report_key(input_dev, BTN_TOUCH, 1);
148 input_report_abs(input_dev, ABS_Y, absy); 151 input_sync(input_dev);
149 input_report_key(input_dev, BTN_TOUCH, 1); 152 } else
150 input_sync(input_dev); 153 ts_dev->bufferedmeasure = 1;
154
155 /* Now make new measurement */
156 ts_dev->prev_absx = atmel_tsadcc_read(ATMEL_TSADCC_CDR3) << 10;
157 ts_dev->prev_absx /= atmel_tsadcc_read(ATMEL_TSADCC_CDR2);
158
159 ts_dev->prev_absy = atmel_tsadcc_read(ATMEL_TSADCC_CDR1) << 10;
160 ts_dev->prev_absy /= atmel_tsadcc_read(ATMEL_TSADCC_CDR0);
151 } 161 }
152 162
153 return IRQ_HANDLED; 163 return IRQ_HANDLED;
@@ -223,6 +233,7 @@ static int __devinit atmel_tsadcc_probe(struct platform_device *pdev)
223 } 233 }
224 234
225 ts_dev->input = input_dev; 235 ts_dev->input = input_dev;
236 ts_dev->bufferedmeasure = 0;
226 237
227 snprintf(ts_dev->phys, sizeof(ts_dev->phys), 238 snprintf(ts_dev->phys, sizeof(ts_dev->phys),
228 "%s/input0", pdev->dev.bus_id); 239 "%s/input0", pdev->dev.bus_id);
diff --git a/drivers/input/touchscreen/mainstone-wm97xx.c b/drivers/input/touchscreen/mainstone-wm97xx.c
index 37a555f37306..ba648750a8d9 100644
--- a/drivers/input/touchscreen/mainstone-wm97xx.c
+++ b/drivers/input/touchscreen/mainstone-wm97xx.c
@@ -3,8 +3,7 @@
3 * Wolfson WM97xx AC97 Codecs. 3 * Wolfson WM97xx AC97 Codecs.
4 * 4 *
5 * Copyright 2004, 2007 Wolfson Microelectronics PLC. 5 * Copyright 2004, 2007 Wolfson Microelectronics PLC.
6 * Author: Liam Girdwood 6 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
7 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
8 * Parts Copyright : Ian Molton <spyro@f2s.com> 7 * Parts Copyright : Ian Molton <spyro@f2s.com>
9 * Andrew Zabolotny <zap@homelink.ru> 8 * Andrew Zabolotny <zap@homelink.ru>
10 * 9 *
@@ -296,6 +295,6 @@ module_init(mainstone_wm97xx_init);
296module_exit(mainstone_wm97xx_exit); 295module_exit(mainstone_wm97xx_exit);
297 296
298/* Module information */ 297/* Module information */
299MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>"); 298MODULE_AUTHOR("Liam Girdwood <lrg@slimlogic.co.uk>");
300MODULE_DESCRIPTION("wm97xx continuous touch driver for mainstone"); 299MODULE_DESCRIPTION("wm97xx continuous touch driver for mainstone");
301MODULE_LICENSE("GPL"); 300MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/wm9705.c b/drivers/input/touchscreen/wm9705.c
index 372efbc694ff..6b5be742c27d 100644
--- a/drivers/input/touchscreen/wm9705.c
+++ b/drivers/input/touchscreen/wm9705.c
@@ -2,8 +2,7 @@
2 * wm9705.c -- Codec driver for Wolfson WM9705 AC97 Codec. 2 * wm9705.c -- Codec driver for Wolfson WM9705 AC97 Codec.
3 * 3 *
4 * Copyright 2003, 2004, 2005, 2006, 2007 Wolfson Microelectronics PLC. 4 * Copyright 2003, 2004, 2005, 2006, 2007 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7 * Parts Copyright : Ian Molton <spyro@f2s.com> 6 * Parts Copyright : Ian Molton <spyro@f2s.com>
8 * Andrew Zabolotny <zap@homelink.ru> 7 * Andrew Zabolotny <zap@homelink.ru>
9 * Russell King <rmk@arm.linux.org.uk> 8 * Russell King <rmk@arm.linux.org.uk>
@@ -347,6 +346,6 @@ struct wm97xx_codec_drv wm9705_codec = {
347EXPORT_SYMBOL_GPL(wm9705_codec); 346EXPORT_SYMBOL_GPL(wm9705_codec);
348 347
349/* Module information */ 348/* Module information */
350MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>"); 349MODULE_AUTHOR("Liam Girdwood <lrg@slimlogic.co.uk>");
351MODULE_DESCRIPTION("WM9705 Touch Screen Driver"); 350MODULE_DESCRIPTION("WM9705 Touch Screen Driver");
352MODULE_LICENSE("GPL"); 351MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/wm9712.c b/drivers/input/touchscreen/wm9712.c
index c8bb1e7335fc..7490b05c3566 100644
--- a/drivers/input/touchscreen/wm9712.c
+++ b/drivers/input/touchscreen/wm9712.c
@@ -2,8 +2,7 @@
2 * wm9712.c -- Codec driver for Wolfson WM9712 AC97 Codecs. 2 * wm9712.c -- Codec driver for Wolfson WM9712 AC97 Codecs.
3 * 3 *
4 * Copyright 2003, 2004, 2005, 2006, 2007 Wolfson Microelectronics PLC. 4 * Copyright 2003, 2004, 2005, 2006, 2007 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7 * Parts Copyright : Ian Molton <spyro@f2s.com> 6 * Parts Copyright : Ian Molton <spyro@f2s.com>
8 * Andrew Zabolotny <zap@homelink.ru> 7 * Andrew Zabolotny <zap@homelink.ru>
9 * Russell King <rmk@arm.linux.org.uk> 8 * Russell King <rmk@arm.linux.org.uk>
@@ -462,6 +461,6 @@ struct wm97xx_codec_drv wm9712_codec = {
462EXPORT_SYMBOL_GPL(wm9712_codec); 461EXPORT_SYMBOL_GPL(wm9712_codec);
463 462
464/* Module information */ 463/* Module information */
465MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>"); 464MODULE_AUTHOR("Liam Girdwood <lrg@slimlogic.co.uk>");
466MODULE_DESCRIPTION("WM9712 Touch Screen Driver"); 465MODULE_DESCRIPTION("WM9712 Touch Screen Driver");
467MODULE_LICENSE("GPL"); 466MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/wm9713.c b/drivers/input/touchscreen/wm9713.c
index 781ee83547e6..238b5132712e 100644
--- a/drivers/input/touchscreen/wm9713.c
+++ b/drivers/input/touchscreen/wm9713.c
@@ -2,8 +2,7 @@
2 * wm9713.c -- Codec touch driver for Wolfson WM9713 AC97 Codec. 2 * wm9713.c -- Codec touch driver for Wolfson WM9713 AC97 Codec.
3 * 3 *
4 * Copyright 2003, 2004, 2005, 2006, 2007, 2008 Wolfson Microelectronics PLC. 4 * Copyright 2003, 2004, 2005, 2006, 2007, 2008 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7 * Parts Copyright : Ian Molton <spyro@f2s.com> 6 * Parts Copyright : Ian Molton <spyro@f2s.com>
8 * Andrew Zabolotny <zap@homelink.ru> 7 * Andrew Zabolotny <zap@homelink.ru>
9 * Russell King <rmk@arm.linux.org.uk> 8 * Russell King <rmk@arm.linux.org.uk>
@@ -476,6 +475,6 @@ struct wm97xx_codec_drv wm9713_codec = {
476EXPORT_SYMBOL_GPL(wm9713_codec); 475EXPORT_SYMBOL_GPL(wm9713_codec);
477 476
478/* Module information */ 477/* Module information */
479MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>"); 478MODULE_AUTHOR("Liam Girdwood <lrg@slimlogic.co.uk>");
480MODULE_DESCRIPTION("WM9713 Touch Screen Driver"); 479MODULE_DESCRIPTION("WM9713 Touch Screen Driver");
481MODULE_LICENSE("GPL"); 480MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c
index d589ab0e3adc..d15aa11d7056 100644
--- a/drivers/input/touchscreen/wm97xx-core.c
+++ b/drivers/input/touchscreen/wm97xx-core.c
@@ -3,8 +3,7 @@
3 * and WM9713 AC97 Codecs. 3 * and WM9713 AC97 Codecs.
4 * 4 *
5 * Copyright 2003, 2004, 2005, 2006, 2007, 2008 Wolfson Microelectronics PLC. 5 * Copyright 2003, 2004, 2005, 2006, 2007, 2008 Wolfson Microelectronics PLC.
6 * Author: Liam Girdwood 6 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
7 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
8 * Parts Copyright : Ian Molton <spyro@f2s.com> 7 * Parts Copyright : Ian Molton <spyro@f2s.com>
9 * Andrew Zabolotny <zap@homelink.ru> 8 * Andrew Zabolotny <zap@homelink.ru>
10 * Russell King <rmk@arm.linux.org.uk> 9 * Russell King <rmk@arm.linux.org.uk>
@@ -824,6 +823,6 @@ module_init(wm97xx_init);
824module_exit(wm97xx_exit); 823module_exit(wm97xx_exit);
825 824
826/* Module information */ 825/* Module information */
827MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>"); 826MODULE_AUTHOR("Liam Girdwood <lrg@slimlogic.co.uk>");
828MODULE_DESCRIPTION("WM97xx Core - Touch Screen / AUX ADC / GPIO Driver"); 827MODULE_DESCRIPTION("WM97xx Core - Touch Screen / AUX ADC / GPIO Driver");
829MODULE_LICENSE("GPL"); 828MODULE_LICENSE("GPL");
diff --git a/drivers/md/faulty.c b/drivers/md/faulty.c
index 268547dbfbd3..f26c1f9a475b 100644
--- a/drivers/md/faulty.c
+++ b/drivers/md/faulty.c
@@ -287,6 +287,8 @@ static int run(mddev_t *mddev)
287 int i; 287 int i;
288 288
289 conf_t *conf = kmalloc(sizeof(*conf), GFP_KERNEL); 289 conf_t *conf = kmalloc(sizeof(*conf), GFP_KERNEL);
290 if (!conf)
291 return -ENOMEM;
290 292
291 for (i=0; i<Modes; i++) { 293 for (i=0; i<Modes; i++) {
292 atomic_set(&conf->counters[i], 0); 294 atomic_set(&conf->counters[i], 0);
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index b9cbee688fae..190147c79e79 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -16,16 +16,8 @@
16 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 16 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17*/ 17*/
18 18
19#include <linux/module.h>
20
21#include <linux/raid/md.h>
22#include <linux/slab.h>
23#include <linux/raid/linear.h> 19#include <linux/raid/linear.h>
24 20
25#define MAJOR_NR MD_MAJOR
26#define MD_DRIVER
27#define MD_PERSONALITY
28
29/* 21/*
30 * find which device holds a particular offset 22 * find which device holds a particular offset
31 */ 23 */
@@ -33,16 +25,15 @@ static inline dev_info_t *which_dev(mddev_t *mddev, sector_t sector)
33{ 25{
34 dev_info_t *hash; 26 dev_info_t *hash;
35 linear_conf_t *conf = mddev_to_conf(mddev); 27 linear_conf_t *conf = mddev_to_conf(mddev);
36 sector_t block = sector >> 1;
37 28
38 /* 29 /*
39 * sector_div(a,b) returns the remainer and sets a to a/b 30 * sector_div(a,b) returns the remainer and sets a to a/b
40 */ 31 */
41 block >>= conf->preshift; 32 sector >>= conf->sector_shift;
42 (void)sector_div(block, conf->hash_spacing); 33 (void)sector_div(sector, conf->spacing);
43 hash = conf->hash_table[block]; 34 hash = conf->hash_table[sector];
44 35
45 while ((sector>>1) >= (hash->size + hash->offset)) 36 while (sector >= hash->num_sectors + hash->start_sector)
46 hash++; 37 hash++;
47 return hash; 38 return hash;
48} 39}
@@ -65,7 +56,7 @@ static int linear_mergeable_bvec(struct request_queue *q,
65 sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev); 56 sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev);
66 57
67 dev0 = which_dev(mddev, sector); 58 dev0 = which_dev(mddev, sector);
68 maxsectors = (dev0->size << 1) - (sector - (dev0->offset<<1)); 59 maxsectors = dev0->num_sectors - (sector - dev0->start_sector);
69 60
70 if (maxsectors < bio_sectors) 61 if (maxsectors < bio_sectors)
71 maxsectors = 0; 62 maxsectors = 0;
@@ -112,8 +103,8 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
112 dev_info_t **table; 103 dev_info_t **table;
113 mdk_rdev_t *rdev; 104 mdk_rdev_t *rdev;
114 int i, nb_zone, cnt; 105 int i, nb_zone, cnt;
115 sector_t min_spacing; 106 sector_t min_sectors;
116 sector_t curr_offset; 107 sector_t curr_sector;
117 struct list_head *tmp; 108 struct list_head *tmp;
118 109
119 conf = kzalloc (sizeof (*conf) + raid_disks*sizeof(dev_info_t), 110 conf = kzalloc (sizeof (*conf) + raid_disks*sizeof(dev_info_t),
@@ -145,7 +136,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
145 mddev->queue->max_sectors > (PAGE_SIZE>>9)) 136 mddev->queue->max_sectors > (PAGE_SIZE>>9))
146 blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); 137 blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
147 138
148 disk->size = rdev->size; 139 disk->num_sectors = rdev->size * 2;
149 conf->array_sectors += rdev->size * 2; 140 conf->array_sectors += rdev->size * 2;
150 141
151 cnt++; 142 cnt++;
@@ -155,34 +146,34 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
155 goto out; 146 goto out;
156 } 147 }
157 148
158 min_spacing = conf->array_sectors / 2; 149 min_sectors = conf->array_sectors;
159 sector_div(min_spacing, PAGE_SIZE/sizeof(struct dev_info *)); 150 sector_div(min_sectors, PAGE_SIZE/sizeof(struct dev_info *));
160 151
161 /* min_spacing is the minimum spacing that will fit the hash 152 /* min_sectors is the minimum spacing that will fit the hash
162 * table in one PAGE. This may be much smaller than needed. 153 * table in one PAGE. This may be much smaller than needed.
163 * We find the smallest non-terminal set of consecutive devices 154 * We find the smallest non-terminal set of consecutive devices
164 * that is larger than min_spacing as use the size of that as 155 * that is larger than min_sectors and use the size of that as
165 * the actual spacing 156 * the actual spacing
166 */ 157 */
167 conf->hash_spacing = conf->array_sectors / 2; 158 conf->spacing = conf->array_sectors;
168 for (i=0; i < cnt-1 ; i++) { 159 for (i=0; i < cnt-1 ; i++) {
169 sector_t sz = 0; 160 sector_t tmp = 0;
170 int j; 161 int j;
171 for (j = i; j < cnt - 1 && sz < min_spacing; j++) 162 for (j = i; j < cnt - 1 && tmp < min_sectors; j++)
172 sz += conf->disks[j].size; 163 tmp += conf->disks[j].num_sectors;
173 if (sz >= min_spacing && sz < conf->hash_spacing) 164 if (tmp >= min_sectors && tmp < conf->spacing)
174 conf->hash_spacing = sz; 165 conf->spacing = tmp;
175 } 166 }
176 167
177 /* hash_spacing may be too large for sector_div to work with, 168 /* spacing may be too large for sector_div to work with,
178 * so we might need to pre-shift 169 * so we might need to pre-shift
179 */ 170 */
180 conf->preshift = 0; 171 conf->sector_shift = 0;
181 if (sizeof(sector_t) > sizeof(u32)) { 172 if (sizeof(sector_t) > sizeof(u32)) {
182 sector_t space = conf->hash_spacing; 173 sector_t space = conf->spacing;
183 while (space > (sector_t)(~(u32)0)) { 174 while (space > (sector_t)(~(u32)0)) {
184 space >>= 1; 175 space >>= 1;
185 conf->preshift++; 176 conf->sector_shift++;
186 } 177 }
187 } 178 }
188 /* 179 /*
@@ -194,9 +185,9 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
194 unsigned round; 185 unsigned round;
195 unsigned long base; 186 unsigned long base;
196 187
197 sz = conf->array_sectors >> (conf->preshift + 1); 188 sz = conf->array_sectors >> conf->sector_shift;
198 sz += 1; /* force round-up */ 189 sz += 1; /* force round-up */
199 base = conf->hash_spacing >> conf->preshift; 190 base = conf->spacing >> conf->sector_shift;
200 round = sector_div(sz, base); 191 round = sector_div(sz, base);
201 nb_zone = sz + (round ? 1 : 0); 192 nb_zone = sz + (round ? 1 : 0);
202 } 193 }
@@ -211,32 +202,31 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
211 * Here we generate the linear hash table 202 * Here we generate the linear hash table
212 * First calculate the device offsets. 203 * First calculate the device offsets.
213 */ 204 */
214 conf->disks[0].offset = 0; 205 conf->disks[0].start_sector = 0;
215 for (i = 1; i < raid_disks; i++) 206 for (i = 1; i < raid_disks; i++)
216 conf->disks[i].offset = 207 conf->disks[i].start_sector =
217 conf->disks[i-1].offset + 208 conf->disks[i-1].start_sector +
218 conf->disks[i-1].size; 209 conf->disks[i-1].num_sectors;
219 210
220 table = conf->hash_table; 211 table = conf->hash_table;
221 curr_offset = 0;
222 i = 0; 212 i = 0;
223 for (curr_offset = 0; 213 for (curr_sector = 0;
224 curr_offset < conf->array_sectors / 2; 214 curr_sector < conf->array_sectors;
225 curr_offset += conf->hash_spacing) { 215 curr_sector += conf->spacing) {
226 216
227 while (i < raid_disks-1 && 217 while (i < raid_disks-1 &&
228 curr_offset >= conf->disks[i+1].offset) 218 curr_sector >= conf->disks[i+1].start_sector)
229 i++; 219 i++;
230 220
231 *table ++ = conf->disks + i; 221 *table ++ = conf->disks + i;
232 } 222 }
233 223
234 if (conf->preshift) { 224 if (conf->sector_shift) {
235 conf->hash_spacing >>= conf->preshift; 225 conf->spacing >>= conf->sector_shift;
236 /* round hash_spacing up so that when we divide by it, 226 /* round spacing up so that when we divide by it,
237 * we err on the side of "too-low", which is safest. 227 * we err on the side of "too-low", which is safest.
238 */ 228 */
239 conf->hash_spacing++; 229 conf->spacing++;
240 } 230 }
241 231
242 BUG_ON(table - conf->hash_table > nb_zone); 232 BUG_ON(table - conf->hash_table > nb_zone);
@@ -317,7 +307,6 @@ static int linear_make_request (struct request_queue *q, struct bio *bio)
317 const int rw = bio_data_dir(bio); 307 const int rw = bio_data_dir(bio);
318 mddev_t *mddev = q->queuedata; 308 mddev_t *mddev = q->queuedata;
319 dev_info_t *tmp_dev; 309 dev_info_t *tmp_dev;
320 sector_t block;
321 int cpu; 310 int cpu;
322 311
323 if (unlikely(bio_barrier(bio))) { 312 if (unlikely(bio_barrier(bio))) {
@@ -332,29 +321,33 @@ static int linear_make_request (struct request_queue *q, struct bio *bio)
332 part_stat_unlock(); 321 part_stat_unlock();
333 322
334 tmp_dev = which_dev(mddev, bio->bi_sector); 323 tmp_dev = which_dev(mddev, bio->bi_sector);
335 block = bio->bi_sector >> 1;
336 324
337 if (unlikely(block >= (tmp_dev->size + tmp_dev->offset) 325 if (unlikely(bio->bi_sector >= (tmp_dev->num_sectors +
338 || block < tmp_dev->offset)) { 326 tmp_dev->start_sector)
327 || (bio->bi_sector <
328 tmp_dev->start_sector))) {
339 char b[BDEVNAME_SIZE]; 329 char b[BDEVNAME_SIZE];
340 330
341 printk("linear_make_request: Block %llu out of bounds on " 331 printk("linear_make_request: Sector %llu out of bounds on "
342 "dev %s size %llu offset %llu\n", 332 "dev %s: %llu sectors, offset %llu\n",
343 (unsigned long long)block, 333 (unsigned long long)bio->bi_sector,
344 bdevname(tmp_dev->rdev->bdev, b), 334 bdevname(tmp_dev->rdev->bdev, b),
345 (unsigned long long)tmp_dev->size, 335 (unsigned long long)tmp_dev->num_sectors,
346 (unsigned long long)tmp_dev->offset); 336 (unsigned long long)tmp_dev->start_sector);
347 bio_io_error(bio); 337 bio_io_error(bio);
348 return 0; 338 return 0;
349 } 339 }
350 if (unlikely(bio->bi_sector + (bio->bi_size >> 9) > 340 if (unlikely(bio->bi_sector + (bio->bi_size >> 9) >
351 (tmp_dev->offset + tmp_dev->size)<<1)) { 341 tmp_dev->start_sector + tmp_dev->num_sectors)) {
352 /* This bio crosses a device boundary, so we have to 342 /* This bio crosses a device boundary, so we have to
353 * split it. 343 * split it.
354 */ 344 */
355 struct bio_pair *bp; 345 struct bio_pair *bp;
346
356 bp = bio_split(bio, 347 bp = bio_split(bio,
357 ((tmp_dev->offset + tmp_dev->size)<<1) - bio->bi_sector); 348 tmp_dev->start_sector + tmp_dev->num_sectors
349 - bio->bi_sector);
350
358 if (linear_make_request(q, &bp->bio1)) 351 if (linear_make_request(q, &bp->bio1))
359 generic_make_request(&bp->bio1); 352 generic_make_request(&bp->bio1);
360 if (linear_make_request(q, &bp->bio2)) 353 if (linear_make_request(q, &bp->bio2))
@@ -364,7 +357,8 @@ static int linear_make_request (struct request_queue *q, struct bio *bio)
364 } 357 }
365 358
366 bio->bi_bdev = tmp_dev->rdev->bdev; 359 bio->bi_bdev = tmp_dev->rdev->bdev;
367 bio->bi_sector = bio->bi_sector - (tmp_dev->offset << 1) + tmp_dev->rdev->data_offset; 360 bio->bi_sector = bio->bi_sector - tmp_dev->start_sector
361 + tmp_dev->rdev->data_offset;
368 362
369 return 1; 363 return 1;
370} 364}
@@ -372,29 +366,6 @@ static int linear_make_request (struct request_queue *q, struct bio *bio)
372static void linear_status (struct seq_file *seq, mddev_t *mddev) 366static void linear_status (struct seq_file *seq, mddev_t *mddev)
373{ 367{
374 368
375#undef MD_DEBUG
376#ifdef MD_DEBUG
377 int j;
378 linear_conf_t *conf = mddev_to_conf(mddev);
379 sector_t s = 0;
380
381 seq_printf(seq, " ");
382 for (j = 0; j < mddev->raid_disks; j++)
383 {
384 char b[BDEVNAME_SIZE];
385 s += conf->smallest_size;
386 seq_printf(seq, "[%s",
387 bdevname(conf->hash_table[j][0].rdev->bdev,b));
388
389 while (s > conf->hash_table[j][0].offset +
390 conf->hash_table[j][0].size)
391 seq_printf(seq, "/%s] ",
392 bdevname(conf->hash_table[j][1].rdev->bdev,b));
393 else
394 seq_printf(seq, "] ");
395 }
396 seq_printf(seq, "\n");
397#endif
398 seq_printf(seq, " %dk rounding", mddev->chunk_size/1024); 369 seq_printf(seq, " %dk rounding", mddev->chunk_size/1024);
399} 370}
400 371
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 0a3a4bdcd4af..aaa3d465de4e 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -32,31 +32,21 @@
32 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 32 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
33*/ 33*/
34 34
35#include <linux/module.h>
36#include <linux/kernel.h>
37#include <linux/kthread.h> 35#include <linux/kthread.h>
38#include <linux/linkage.h>
39#include <linux/raid/md.h> 36#include <linux/raid/md.h>
40#include <linux/raid/bitmap.h> 37#include <linux/raid/bitmap.h>
41#include <linux/sysctl.h> 38#include <linux/sysctl.h>
42#include <linux/buffer_head.h> /* for invalidate_bdev */ 39#include <linux/buffer_head.h> /* for invalidate_bdev */
43#include <linux/poll.h> 40#include <linux/poll.h>
44#include <linux/mutex.h>
45#include <linux/ctype.h> 41#include <linux/ctype.h>
46#include <linux/freezer.h> 42#include <linux/hdreg.h>
47 43#include <linux/proc_fs.h>
48#include <linux/init.h> 44#include <linux/random.h>
49 45#include <linux/reboot.h>
50#include <linux/file.h> 46#include <linux/file.h>
51 47#include <linux/delay.h>
52#ifdef CONFIG_KMOD
53#include <linux/kmod.h>
54#endif
55
56#include <asm/unaligned.h>
57 48
58#define MAJOR_NR MD_MAJOR 49#define MAJOR_NR MD_MAJOR
59#define MD_DRIVER
60 50
61/* 63 partitions with the alternate major number (mdp) */ 51/* 63 partitions with the alternate major number (mdp) */
62#define MdpMinorShift 6 52#define MdpMinorShift 6
@@ -66,7 +56,7 @@
66 56
67 57
68#ifndef MODULE 58#ifndef MODULE
69static void autostart_arrays (int part); 59static void autostart_arrays(int part);
70#endif 60#endif
71 61
72static LIST_HEAD(pers_list); 62static LIST_HEAD(pers_list);
@@ -212,7 +202,7 @@ static DEFINE_SPINLOCK(all_mddevs_lock);
212 ) 202 )
213 203
214 204
215static int md_fail_request (struct request_queue *q, struct bio *bio) 205static int md_fail_request(struct request_queue *q, struct bio *bio)
216{ 206{
217 bio_io_error(bio); 207 bio_io_error(bio);
218 return 0; 208 return 0;
@@ -2106,8 +2096,6 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
2106 2096
2107 if (strict_strtoull(buf, 10, &size) < 0) 2097 if (strict_strtoull(buf, 10, &size) < 0)
2108 return -EINVAL; 2098 return -EINVAL;
2109 if (size < my_mddev->size)
2110 return -EINVAL;
2111 if (my_mddev->pers && rdev->raid_disk >= 0) { 2099 if (my_mddev->pers && rdev->raid_disk >= 0) {
2112 if (my_mddev->persistent) { 2100 if (my_mddev->persistent) {
2113 size = super_types[my_mddev->major_version]. 2101 size = super_types[my_mddev->major_version].
@@ -2118,9 +2106,9 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
2118 size = (rdev->bdev->bd_inode->i_size >> 10); 2106 size = (rdev->bdev->bd_inode->i_size >> 10);
2119 size -= rdev->data_offset/2; 2107 size -= rdev->data_offset/2;
2120 } 2108 }
2121 if (size < my_mddev->size)
2122 return -EINVAL; /* component must fit device */
2123 } 2109 }
2110 if (size < my_mddev->size)
2111 return -EINVAL; /* component must fit device */
2124 2112
2125 rdev->size = size; 2113 rdev->size = size;
2126 if (size > oldsize && my_mddev->external) { 2114 if (size > oldsize && my_mddev->external) {
@@ -2406,12 +2394,11 @@ safe_delay_store(mddev_t *mddev, const char *cbuf, size_t len)
2406 int i; 2394 int i;
2407 unsigned long msec; 2395 unsigned long msec;
2408 char buf[30]; 2396 char buf[30];
2409 char *e; 2397
2410 /* remove a period, and count digits after it */ 2398 /* remove a period, and count digits after it */
2411 if (len >= sizeof(buf)) 2399 if (len >= sizeof(buf))
2412 return -EINVAL; 2400 return -EINVAL;
2413 strlcpy(buf, cbuf, len); 2401 strlcpy(buf, cbuf, sizeof(buf));
2414 buf[len] = 0;
2415 for (i=0; i<len; i++) { 2402 for (i=0; i<len; i++) {
2416 if (dot) { 2403 if (dot) {
2417 if (isdigit(buf[i])) { 2404 if (isdigit(buf[i])) {
@@ -2424,8 +2411,7 @@ safe_delay_store(mddev_t *mddev, const char *cbuf, size_t len)
2424 buf[i] = 0; 2411 buf[i] = 0;
2425 } 2412 }
2426 } 2413 }
2427 msec = simple_strtoul(buf, &e, 10); 2414 if (strict_strtoul(buf, 10, &msec) < 0)
2428 if (e == buf || (*e && *e != '\n'))
2429 return -EINVAL; 2415 return -EINVAL;
2430 msec = (msec * 1000) / scale; 2416 msec = (msec * 1000) / scale;
2431 if (msec == 0) 2417 if (msec == 0)
@@ -2727,9 +2713,9 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len)
2727 break; 2713 break;
2728 case read_auto: 2714 case read_auto:
2729 if (mddev->pers) { 2715 if (mddev->pers) {
2730 if (mddev->ro != 1) 2716 if (mddev->ro == 0)
2731 err = do_md_stop(mddev, 1, 0); 2717 err = do_md_stop(mddev, 1, 0);
2732 else 2718 else if (mddev->ro == 1)
2733 err = restart_array(mddev); 2719 err = restart_array(mddev);
2734 if (err == 0) { 2720 if (err == 0) {
2735 mddev->ro = 2; 2721 mddev->ro = 2;
@@ -2945,7 +2931,13 @@ metadata_store(mddev_t *mddev, const char *buf, size_t len)
2945{ 2931{
2946 int major, minor; 2932 int major, minor;
2947 char *e; 2933 char *e;
2948 if (!list_empty(&mddev->disks)) 2934 /* Changing the details of 'external' metadata is
2935 * always permitted. Otherwise there must be
2936 * no devices attached to the array.
2937 */
2938 if (mddev->external && strncmp(buf, "external:", 9) == 0)
2939 ;
2940 else if (!list_empty(&mddev->disks))
2949 return -EBUSY; 2941 return -EBUSY;
2950 2942
2951 if (cmd_match(buf, "none")) { 2943 if (cmd_match(buf, "none")) {
@@ -3527,17 +3519,12 @@ static int do_md_run(mddev_t * mddev)
3527 return -EINVAL; 3519 return -EINVAL;
3528 } 3520 }
3529 /* 3521 /*
3530 * chunk-size has to be a power of 2 and multiples of PAGE_SIZE 3522 * chunk-size has to be a power of 2
3531 */ 3523 */
3532 if ( (1 << ffz(~chunk_size)) != chunk_size) { 3524 if ( (1 << ffz(~chunk_size)) != chunk_size) {
3533 printk(KERN_ERR "chunk_size of %d not valid\n", chunk_size); 3525 printk(KERN_ERR "chunk_size of %d not valid\n", chunk_size);
3534 return -EINVAL; 3526 return -EINVAL;
3535 } 3527 }
3536 if (chunk_size < PAGE_SIZE) {
3537 printk(KERN_ERR "too small chunk_size: %d < %ld\n",
3538 chunk_size, PAGE_SIZE);
3539 return -EINVAL;
3540 }
3541 3528
3542 /* devices must have minimum size of one chunk */ 3529 /* devices must have minimum size of one chunk */
3543 rdev_for_each(rdev, tmp, mddev) { 3530 rdev_for_each(rdev, tmp, mddev) {
@@ -3555,12 +3542,10 @@ static int do_md_run(mddev_t * mddev)
3555 } 3542 }
3556 } 3543 }
3557 3544
3558#ifdef CONFIG_KMOD
3559 if (mddev->level != LEVEL_NONE) 3545 if (mddev->level != LEVEL_NONE)
3560 request_module("md-level-%d", mddev->level); 3546 request_module("md-level-%d", mddev->level);
3561 else if (mddev->clevel[0]) 3547 else if (mddev->clevel[0])
3562 request_module("md-%s", mddev->clevel); 3548 request_module("md-%s", mddev->clevel);
3563#endif
3564 3549
3565 /* 3550 /*
3566 * Drop all container device buffers, from now on 3551 * Drop all container device buffers, from now on
@@ -3971,10 +3956,10 @@ static void autorun_array(mddev_t *mddev)
3971 } 3956 }
3972 printk("\n"); 3957 printk("\n");
3973 3958
3974 err = do_md_run (mddev); 3959 err = do_md_run(mddev);
3975 if (err) { 3960 if (err) {
3976 printk(KERN_WARNING "md: do_md_run() returned %d\n", err); 3961 printk(KERN_WARNING "md: do_md_run() returned %d\n", err);
3977 do_md_stop (mddev, 0, 0); 3962 do_md_stop(mddev, 0, 0);
3978 } 3963 }
3979} 3964}
3980 3965
@@ -4333,7 +4318,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
4333 4318
4334 if (!(info->state & (1<<MD_DISK_FAULTY))) { 4319 if (!(info->state & (1<<MD_DISK_FAULTY))) {
4335 int err; 4320 int err;
4336 rdev = md_import_device (dev, -1, 0); 4321 rdev = md_import_device(dev, -1, 0);
4337 if (IS_ERR(rdev)) { 4322 if (IS_ERR(rdev)) {
4338 printk(KERN_WARNING 4323 printk(KERN_WARNING
4339 "md: error, md_import_device() returned %ld\n", 4324 "md: error, md_import_device() returned %ld\n",
@@ -4415,7 +4400,7 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev)
4415 return -EINVAL; 4400 return -EINVAL;
4416 } 4401 }
4417 4402
4418 rdev = md_import_device (dev, -1, 0); 4403 rdev = md_import_device(dev, -1, 0);
4419 if (IS_ERR(rdev)) { 4404 if (IS_ERR(rdev)) {
4420 printk(KERN_WARNING 4405 printk(KERN_WARNING
4421 "md: error, md_import_device() returned %ld\n", 4406 "md: error, md_import_device() returned %ld\n",
@@ -4934,11 +4919,11 @@ static int md_ioctl(struct inode *inode, struct file *file,
4934 goto done_unlock; 4919 goto done_unlock;
4935 4920
4936 case STOP_ARRAY: 4921 case STOP_ARRAY:
4937 err = do_md_stop (mddev, 0, 1); 4922 err = do_md_stop(mddev, 0, 1);
4938 goto done_unlock; 4923 goto done_unlock;
4939 4924
4940 case STOP_ARRAY_RO: 4925 case STOP_ARRAY_RO:
4941 err = do_md_stop (mddev, 1, 1); 4926 err = do_md_stop(mddev, 1, 1);
4942 goto done_unlock; 4927 goto done_unlock;
4943 4928
4944 } 4929 }
@@ -4987,7 +4972,7 @@ static int md_ioctl(struct inode *inode, struct file *file,
4987 goto done_unlock; 4972 goto done_unlock;
4988 4973
4989 case RUN_ARRAY: 4974 case RUN_ARRAY:
4990 err = do_md_run (mddev); 4975 err = do_md_run(mddev);
4991 goto done_unlock; 4976 goto done_unlock;
4992 4977
4993 case SET_BITMAP_FILE: 4978 case SET_BITMAP_FILE:
@@ -5425,11 +5410,11 @@ static int md_seq_show(struct seq_file *seq, void *v)
5425 seq_printf(seq, " super non-persistent"); 5410 seq_printf(seq, " super non-persistent");
5426 5411
5427 if (mddev->pers) { 5412 if (mddev->pers) {
5428 mddev->pers->status (seq, mddev); 5413 mddev->pers->status(seq, mddev);
5429 seq_printf(seq, "\n "); 5414 seq_printf(seq, "\n ");
5430 if (mddev->pers->sync_request) { 5415 if (mddev->pers->sync_request) {
5431 if (mddev->curr_resync > 2) { 5416 if (mddev->curr_resync > 2) {
5432 status_resync (seq, mddev); 5417 status_resync(seq, mddev);
5433 seq_printf(seq, "\n "); 5418 seq_printf(seq, "\n ");
5434 } else if (mddev->curr_resync == 1 || mddev->curr_resync == 2) 5419 } else if (mddev->curr_resync == 1 || mddev->curr_resync == 2)
5435 seq_printf(seq, "\tresync=DELAYED\n "); 5420 seq_printf(seq, "\tresync=DELAYED\n ");
@@ -6260,7 +6245,7 @@ static int md_notify_reboot(struct notifier_block *this,
6260 * appears to still be in use. Hence 6245 * appears to still be in use. Hence
6261 * the '100'. 6246 * the '100'.
6262 */ 6247 */
6263 do_md_stop (mddev, 1, 100); 6248 do_md_stop(mddev, 1, 100);
6264 mddev_unlock(mddev); 6249 mddev_unlock(mddev);
6265 } 6250 }
6266 /* 6251 /*
@@ -6304,7 +6289,7 @@ static int __init md_init(void)
6304 raid_table_header = register_sysctl_table(raid_root_table); 6289 raid_table_header = register_sysctl_table(raid_root_table);
6305 6290
6306 md_geninit(); 6291 md_geninit();
6307 return (0); 6292 return 0;
6308} 6293}
6309 6294
6310 6295
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index 8bb8794129b3..8744014b9d80 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -19,16 +19,7 @@
19 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */ 20 */
21 21
22#include <linux/module.h>
23#include <linux/slab.h>
24#include <linux/spinlock.h>
25#include <linux/raid/multipath.h> 22#include <linux/raid/multipath.h>
26#include <linux/buffer_head.h>
27#include <asm/atomic.h>
28
29#define MAJOR_NR MD_MAJOR
30#define MD_DRIVER
31#define MD_PERSONALITY
32 23
33#define MAX_WORK_PER_DISK 128 24#define MAX_WORK_PER_DISK 128
34 25
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index 53508a8a981d..8ac6488ad0dc 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -18,13 +18,8 @@
18 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/ 19*/
20 20
21#include <linux/module.h>
22#include <linux/raid/raid0.h> 21#include <linux/raid/raid0.h>
23 22
24#define MAJOR_NR MD_MAJOR
25#define MD_DRIVER
26#define MD_PERSONALITY
27
28static void raid0_unplug(struct request_queue *q) 23static void raid0_unplug(struct request_queue *q)
29{ 24{
30 mddev_t *mddev = q->queuedata; 25 mddev_t *mddev = q->queuedata;
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index b9764429d856..9c788e2489b1 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -32,6 +32,7 @@
32 */ 32 */
33 33
34#include "dm-bio-list.h" 34#include "dm-bio-list.h"
35#include <linux/delay.h>
35#include <linux/raid/raid1.h> 36#include <linux/raid/raid1.h>
36#include <linux/raid/bitmap.h> 37#include <linux/raid/bitmap.h>
37 38
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 8bdc9bfc2887..da5129a24b18 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -19,6 +19,7 @@
19 */ 19 */
20 20
21#include "dm-bio-list.h" 21#include "dm-bio-list.h"
22#include <linux/delay.h>
22#include <linux/raid/raid10.h> 23#include <linux/raid/raid10.h>
23#include <linux/raid/bitmap.h> 24#include <linux/raid/bitmap.h>
24 25
@@ -2028,8 +2029,9 @@ static int run(mddev_t *mddev)
2028 int nc, fc, fo; 2029 int nc, fc, fo;
2029 sector_t stride, size; 2030 sector_t stride, size;
2030 2031
2031 if (mddev->chunk_size == 0) { 2032 if (mddev->chunk_size < PAGE_SIZE) {
2032 printk(KERN_ERR "md/raid10: non-zero chunk size required.\n"); 2033 printk(KERN_ERR "md/raid10: chunk size must be "
2034 "at least PAGE_SIZE(%ld).\n", PAGE_SIZE);
2033 return -EINVAL; 2035 return -EINVAL;
2034 } 2036 }
2035 2037
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index ae16794bef20..a36a7435edf5 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -43,12 +43,7 @@
43 * miss any bits. 43 * miss any bits.
44 */ 44 */
45 45
46#include <linux/module.h>
47#include <linux/slab.h>
48#include <linux/highmem.h>
49#include <linux/bitops.h>
50#include <linux/kthread.h> 46#include <linux/kthread.h>
51#include <asm/atomic.h>
52#include "raid6.h" 47#include "raid6.h"
53 48
54#include <linux/raid/bitmap.h> 49#include <linux/raid/bitmap.h>
@@ -275,7 +270,7 @@ static int grow_buffers(struct stripe_head *sh, int num)
275 return 0; 270 return 0;
276} 271}
277 272
278static void raid5_build_block (struct stripe_head *sh, int i); 273static void raid5_build_block(struct stripe_head *sh, int i);
279 274
280static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx, int disks) 275static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx, int disks)
281{ 276{
@@ -1151,7 +1146,7 @@ static void raid5_end_read_request(struct bio * bi, int error)
1151 release_stripe(sh); 1146 release_stripe(sh);
1152} 1147}
1153 1148
1154static void raid5_end_write_request (struct bio *bi, int error) 1149static void raid5_end_write_request(struct bio *bi, int error)
1155{ 1150{
1156 struct stripe_head *sh = bi->bi_private; 1151 struct stripe_head *sh = bi->bi_private;
1157 raid5_conf_t *conf = sh->raid_conf; 1152 raid5_conf_t *conf = sh->raid_conf;
@@ -1183,7 +1178,7 @@ static void raid5_end_write_request (struct bio *bi, int error)
1183 1178
1184static sector_t compute_blocknr(struct stripe_head *sh, int i); 1179static sector_t compute_blocknr(struct stripe_head *sh, int i);
1185 1180
1186static void raid5_build_block (struct stripe_head *sh, int i) 1181static void raid5_build_block(struct stripe_head *sh, int i)
1187{ 1182{
1188 struct r5dev *dev = &sh->dev[i]; 1183 struct r5dev *dev = &sh->dev[i];
1189 1184
@@ -1221,10 +1216,10 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
1221 set_bit(MD_RECOVERY_INTR, &mddev->recovery); 1216 set_bit(MD_RECOVERY_INTR, &mddev->recovery);
1222 } 1217 }
1223 set_bit(Faulty, &rdev->flags); 1218 set_bit(Faulty, &rdev->flags);
1224 printk (KERN_ALERT 1219 printk(KERN_ALERT
1225 "raid5: Disk failure on %s, disabling device.\n" 1220 "raid5: Disk failure on %s, disabling device.\n"
1226 "raid5: Operation continuing on %d devices.\n", 1221 "raid5: Operation continuing on %d devices.\n",
1227 bdevname(rdev->bdev,b), conf->raid_disks - mddev->degraded); 1222 bdevname(rdev->bdev,b), conf->raid_disks - mddev->degraded);
1228 } 1223 }
1229} 1224}
1230 1225
@@ -1320,8 +1315,8 @@ static sector_t raid5_compute_sector(sector_t r_sector, unsigned int raid_disks,
1320 *dd_idx = (*pd_idx + 2 + *dd_idx) % raid_disks; 1315 *dd_idx = (*pd_idx + 2 + *dd_idx) % raid_disks;
1321 break; 1316 break;
1322 default: 1317 default:
1323 printk (KERN_CRIT "raid6: unsupported algorithm %d\n", 1318 printk(KERN_CRIT "raid6: unsupported algorithm %d\n",
1324 conf->algorithm); 1319 conf->algorithm);
1325 } 1320 }
1326 break; 1321 break;
1327 } 1322 }
@@ -1396,8 +1391,8 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i)
1396 } 1391 }
1397 break; 1392 break;
1398 default: 1393 default:
1399 printk (KERN_CRIT "raid6: unsupported algorithm %d\n", 1394 printk(KERN_CRIT "raid6: unsupported algorithm %d\n",
1400 conf->algorithm); 1395 conf->algorithm);
1401 } 1396 }
1402 break; 1397 break;
1403 } 1398 }
@@ -1405,7 +1400,7 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i)
1405 chunk_number = stripe * data_disks + i; 1400 chunk_number = stripe * data_disks + i;
1406 r_sector = (sector_t)chunk_number * sectors_per_chunk + chunk_offset; 1401 r_sector = (sector_t)chunk_number * sectors_per_chunk + chunk_offset;
1407 1402
1408 check = raid5_compute_sector (r_sector, raid_disks, data_disks, &dummy1, &dummy2, conf); 1403 check = raid5_compute_sector(r_sector, raid_disks, data_disks, &dummy1, &dummy2, conf);
1409 if (check != sh->sector || dummy1 != dd_idx || dummy2 != sh->pd_idx) { 1404 if (check != sh->sector || dummy1 != dd_idx || dummy2 != sh->pd_idx) {
1410 printk(KERN_ERR "compute_blocknr: map not correct\n"); 1405 printk(KERN_ERR "compute_blocknr: map not correct\n");
1411 return 0; 1406 return 0;
@@ -4012,6 +4007,13 @@ static int run(mddev_t *mddev)
4012 return -EIO; 4007 return -EIO;
4013 } 4008 }
4014 4009
4010 if (mddev->chunk_size < PAGE_SIZE) {
4011 printk(KERN_ERR "md/raid5: chunk_size must be at least "
4012 "PAGE_SIZE but %d < %ld\n",
4013 mddev->chunk_size, PAGE_SIZE);
4014 return -EINVAL;
4015 }
4016
4015 if (mddev->reshape_position != MaxSector) { 4017 if (mddev->reshape_position != MaxSector) {
4016 /* Check that we can continue the reshape. 4018 /* Check that we can continue the reshape.
4017 * Currently only disks can change, it must 4019 * Currently only disks can change, it must
@@ -4289,7 +4291,7 @@ static int stop(mddev_t *mddev)
4289} 4291}
4290 4292
4291#ifdef DEBUG 4293#ifdef DEBUG
4292static void print_sh (struct seq_file *seq, struct stripe_head *sh) 4294static void print_sh(struct seq_file *seq, struct stripe_head *sh)
4293{ 4295{
4294 int i; 4296 int i;
4295 4297
@@ -4305,7 +4307,7 @@ static void print_sh (struct seq_file *seq, struct stripe_head *sh)
4305 seq_printf(seq, "\n"); 4307 seq_printf(seq, "\n");
4306} 4308}
4307 4309
4308static void printall (struct seq_file *seq, raid5_conf_t *conf) 4310static void printall(struct seq_file *seq, raid5_conf_t *conf)
4309{ 4311{
4310 struct stripe_head *sh; 4312 struct stripe_head *sh;
4311 struct hlist_node *hn; 4313 struct hlist_node *hn;
@@ -4323,7 +4325,7 @@ static void printall (struct seq_file *seq, raid5_conf_t *conf)
4323} 4325}
4324#endif 4326#endif
4325 4327
4326static void status (struct seq_file *seq, mddev_t *mddev) 4328static void status(struct seq_file *seq, mddev_t *mddev)
4327{ 4329{
4328 raid5_conf_t *conf = (raid5_conf_t *) mddev->private; 4330 raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
4329 int i; 4331 int i;
diff --git a/drivers/md/raid6.h b/drivers/md/raid6.h
index 31cbee71365f..98dcde88470e 100644
--- a/drivers/md/raid6.h
+++ b/drivers/md/raid6.h
@@ -18,15 +18,6 @@
18/* Set to 1 to use kernel-wide empty_zero_page */ 18/* Set to 1 to use kernel-wide empty_zero_page */
19#define RAID6_USE_EMPTY_ZERO_PAGE 0 19#define RAID6_USE_EMPTY_ZERO_PAGE 0
20 20
21#include <linux/module.h>
22#include <linux/stddef.h>
23#include <linux/compiler.h>
24#include <linux/types.h>
25#include <linux/kernel.h>
26#include <linux/errno.h>
27#include <linux/mempool.h>
28#include <linux/list.h>
29#include <linux/vmalloc.h>
30#include <linux/raid/md.h> 21#include <linux/raid/md.h>
31#include <linux/raid/raid5.h> 22#include <linux/raid/raid5.h>
32 23
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c
index c325e926de8a..1798b779a25a 100644
--- a/drivers/media/video/cpia.c
+++ b/drivers/media/video/cpia.c
@@ -39,10 +39,6 @@
39#include <asm/io.h> 39#include <asm/io.h>
40#include <linux/mutex.h> 40#include <linux/mutex.h>
41 41
42#ifdef CONFIG_KMOD
43#include <linux/kmod.h>
44#endif
45
46#include "cpia.h" 42#include "cpia.h"
47 43
48static int video_nr = -1; 44static int video_nr = -1;
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c
index b26b563a0b0a..9e4f50639975 100644
--- a/drivers/media/video/usbvision/usbvision-core.c
+++ b/drivers/media/video/usbvision/usbvision-core.c
@@ -45,10 +45,6 @@
45 45
46#include <linux/workqueue.h> 46#include <linux/workqueue.h>
47 47
48#ifdef CONFIG_KMOD
49#include <linux/kmod.h>
50#endif
51
52#include "usbvision.h" 48#include "usbvision.h"
53 49
54static unsigned int core_debug; 50static unsigned int core_debug;
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index e10b256aeba4..77aeb39b2750 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -69,10 +69,6 @@
69 69
70#include <linux/workqueue.h> 70#include <linux/workqueue.h>
71 71
72#ifdef CONFIG_KMOD
73#include <linux/kmod.h>
74#endif
75
76#include "usbvision.h" 72#include "usbvision.h"
77#include "usbvision-cards.h" 73#include "usbvision-cards.h"
78 74
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
index 79937d1031fc..928cb4037372 100644
--- a/drivers/media/video/v4l1-compat.c
+++ b/drivers/media/video/v4l1-compat.c
@@ -36,10 +36,6 @@
36#include <asm/system.h> 36#include <asm/system.h>
37#include <asm/pgtable.h> 37#include <asm/pgtable.h>
38 38
39#ifdef CONFIG_KMOD
40#include <linux/kmod.h>
41#endif
42
43static unsigned int debug; 39static unsigned int debug;
44module_param(debug, int, 0644); 40module_param(debug, int, 0644);
45MODULE_PARM_DESC(debug, "enable debug messages"); 41MODULE_PARM_DESC(debug, "enable debug messages");
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index 20c3be8617ea..846763d7349e 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -60,10 +60,6 @@
60#include <media/v4l2-common.h> 60#include <media/v4l2-common.h>
61#include <media/v4l2-chip-ident.h> 61#include <media/v4l2-chip-ident.h>
62 62
63#ifdef CONFIG_KMOD
64#include <linux/kmod.h>
65#endif
66
67#include <linux/videodev2.h> 63#include <linux/videodev2.h>
68 64
69MODULE_AUTHOR("Bill Dirks, Justin Schoeman, Gerd Knorr"); 65MODULE_AUTHOR("Bill Dirks, Justin Schoeman, Gerd Knorr");
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
index 8ec57df1904f..1efc5f3462c6 100644
--- a/drivers/media/video/vino.c
+++ b/drivers/media/video/vino.c
@@ -30,10 +30,7 @@
30#include <linux/mm.h> 30#include <linux/mm.h>
31#include <linux/time.h> 31#include <linux/time.h>
32#include <linux/version.h> 32#include <linux/version.h>
33
34#ifdef CONFIG_KMOD
35#include <linux/kmod.h> 33#include <linux/kmod.h>
36#endif
37 34
38#include <linux/i2c.h> 35#include <linux/i2c.h>
39#include <linux/i2c-algo-sgi.h> 36#include <linux/i2c-algo-sgi.h>
@@ -4634,7 +4631,7 @@ static int __init vino_module_init(void)
4634 } 4631 }
4635 vino_init_stage++; 4632 vino_init_stage++;
4636 4633
4637#if defined(CONFIG_KMOD) && defined(MODULE) 4634#ifdef MODULE
4638 request_module("saa7191"); 4635 request_module("saa7191");
4639 request_module("indycam"); 4636 request_module("indycam");
4640#endif 4637#endif
diff --git a/drivers/media/video/w9968cf.c b/drivers/media/video/w9968cf.c
index 11edf79f57be..dcd45dbd82dc 100644
--- a/drivers/media/video/w9968cf.c
+++ b/drivers/media/video/w9968cf.c
@@ -111,7 +111,7 @@ static int specific_debug = W9968CF_SPECIFIC_DEBUG;
111 111
112static unsigned int param_nv[24]; /* number of values per parameter */ 112static unsigned int param_nv[24]; /* number of values per parameter */
113 113
114#ifdef CONFIG_KMOD 114#ifdef CONFIG_MODULES
115module_param(ovmod_load, bool, 0644); 115module_param(ovmod_load, bool, 0644);
116#endif 116#endif
117module_param(simcams, ushort, 0644); 117module_param(simcams, ushort, 0644);
@@ -144,7 +144,7 @@ module_param(debug, ushort, 0644);
144module_param(specific_debug, bool, 0644); 144module_param(specific_debug, bool, 0644);
145#endif 145#endif
146 146
147#ifdef CONFIG_KMOD 147#ifdef CONFIG_MODULES
148MODULE_PARM_DESC(ovmod_load, 148MODULE_PARM_DESC(ovmod_load,
149 "\n<0|1> Automatic 'ovcamchip' module loading." 149 "\n<0|1> Automatic 'ovcamchip' module loading."
150 "\n0 disabled, 1 enabled." 150 "\n0 disabled, 1 enabled."
diff --git a/drivers/message/i2o/Makefile b/drivers/message/i2o/Makefile
index 2c2e39aa1efa..b0982dacfd0a 100644
--- a/drivers/message/i2o/Makefile
+++ b/drivers/message/i2o/Makefile
@@ -5,7 +5,7 @@
5# In the future, some of these should be built conditionally. 5# In the future, some of these should be built conditionally.
6# 6#
7 7
8i2o_core-y += iop.o driver.o device.o debug.o pci.o exec-osm.o 8i2o_core-y += iop.o driver.o device.o debug.o pci.o exec-osm.o memory.o
9i2o_bus-y += bus-osm.o 9i2o_bus-y += bus-osm.o
10i2o_config-y += config-osm.o 10i2o_config-y += config-osm.o
11obj-$(CONFIG_I2O) += i2o_core.o 11obj-$(CONFIG_I2O) += i2o_core.o
diff --git a/drivers/message/i2o/device.c b/drivers/message/i2o/device.c
index 8774c670e668..54c2e9ae23e5 100644
--- a/drivers/message/i2o/device.c
+++ b/drivers/message/i2o/device.c
@@ -467,7 +467,7 @@ int i2o_parm_issue(struct i2o_device *i2o_dev, int cmd, void *oplist,
467 467
468 res.virt = NULL; 468 res.virt = NULL;
469 469
470 if (i2o_dma_alloc(dev, &res, reslen, GFP_KERNEL)) 470 if (i2o_dma_alloc(dev, &res, reslen))
471 return -ENOMEM; 471 return -ENOMEM;
472 472
473 msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); 473 msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c
index 6cbcc21de518..56faef1a1d55 100644
--- a/drivers/message/i2o/exec-osm.c
+++ b/drivers/message/i2o/exec-osm.c
@@ -388,8 +388,8 @@ static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind)
388 388
389 dev = &c->pdev->dev; 389 dev = &c->pdev->dev;
390 390
391 if (i2o_dma_realloc 391 if (i2o_dma_realloc(dev, &c->dlct,
392 (dev, &c->dlct, le32_to_cpu(sb->expected_lct_size), GFP_KERNEL)) 392 le32_to_cpu(sb->expected_lct_size)))
393 return -ENOMEM; 393 return -ENOMEM;
394 394
395 msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); 395 msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c
index 4238de98d4a6..a3fabdbe6ca6 100644
--- a/drivers/message/i2o/i2o_config.c
+++ b/drivers/message/i2o/i2o_config.c
@@ -260,7 +260,7 @@ static int i2o_cfg_swdl(unsigned long arg)
260 if (IS_ERR(msg)) 260 if (IS_ERR(msg))
261 return PTR_ERR(msg); 261 return PTR_ERR(msg);
262 262
263 if (i2o_dma_alloc(&c->pdev->dev, &buffer, fragsize, GFP_KERNEL)) { 263 if (i2o_dma_alloc(&c->pdev->dev, &buffer, fragsize)) {
264 i2o_msg_nop(c, msg); 264 i2o_msg_nop(c, msg);
265 return -ENOMEM; 265 return -ENOMEM;
266 } 266 }
@@ -339,7 +339,7 @@ static int i2o_cfg_swul(unsigned long arg)
339 if (IS_ERR(msg)) 339 if (IS_ERR(msg))
340 return PTR_ERR(msg); 340 return PTR_ERR(msg);
341 341
342 if (i2o_dma_alloc(&c->pdev->dev, &buffer, fragsize, GFP_KERNEL)) { 342 if (i2o_dma_alloc(&c->pdev->dev, &buffer, fragsize)) {
343 i2o_msg_nop(c, msg); 343 i2o_msg_nop(c, msg);
344 return -ENOMEM; 344 return -ENOMEM;
345 } 345 }
@@ -634,9 +634,7 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd,
634 sg_size = sg[i].flag_count & 0xffffff; 634 sg_size = sg[i].flag_count & 0xffffff;
635 p = &(sg_list[sg_index]); 635 p = &(sg_list[sg_index]);
636 /* Allocate memory for the transfer */ 636 /* Allocate memory for the transfer */
637 if (i2o_dma_alloc 637 if (i2o_dma_alloc(&c->pdev->dev, p, sg_size)) {
638 (&c->pdev->dev, p, sg_size,
639 PCI_DMA_BIDIRECTIONAL)) {
640 printk(KERN_DEBUG 638 printk(KERN_DEBUG
641 "%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n", 639 "%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
642 c->name, sg_size, i, sg_count); 640 c->name, sg_size, i, sg_count);
@@ -780,12 +778,11 @@ static int i2o_cfg_passthru(unsigned long arg)
780 u32 size = 0; 778 u32 size = 0;
781 u32 reply_size = 0; 779 u32 reply_size = 0;
782 u32 rcode = 0; 780 u32 rcode = 0;
783 void *sg_list[SG_TABLESIZE]; 781 struct i2o_dma sg_list[SG_TABLESIZE];
784 u32 sg_offset = 0; 782 u32 sg_offset = 0;
785 u32 sg_count = 0; 783 u32 sg_count = 0;
786 int sg_index = 0; 784 int sg_index = 0;
787 u32 i = 0; 785 u32 i = 0;
788 void *p = NULL;
789 i2o_status_block *sb; 786 i2o_status_block *sb;
790 struct i2o_message *msg; 787 struct i2o_message *msg;
791 unsigned int iop; 788 unsigned int iop;
@@ -842,6 +839,7 @@ static int i2o_cfg_passthru(unsigned long arg)
842 memset(sg_list, 0, sizeof(sg_list[0]) * SG_TABLESIZE); 839 memset(sg_list, 0, sizeof(sg_list[0]) * SG_TABLESIZE);
843 if (sg_offset) { 840 if (sg_offset) {
844 struct sg_simple_element *sg; 841 struct sg_simple_element *sg;
842 struct i2o_dma *p;
845 843
846 if (sg_offset * 4 >= size) { 844 if (sg_offset * 4 >= size) {
847 rcode = -EFAULT; 845 rcode = -EFAULT;
@@ -871,22 +869,22 @@ static int i2o_cfg_passthru(unsigned long arg)
871 goto sg_list_cleanup; 869 goto sg_list_cleanup;
872 } 870 }
873 sg_size = sg[i].flag_count & 0xffffff; 871 sg_size = sg[i].flag_count & 0xffffff;
872 p = &(sg_list[sg_index]);
873 if (i2o_dma_alloc(&c->pdev->dev, p, sg_size)) {
874 /* Allocate memory for the transfer */ 874 /* Allocate memory for the transfer */
875 p = kmalloc(sg_size, GFP_KERNEL);
876 if (!p) {
877 printk(KERN_DEBUG 875 printk(KERN_DEBUG
878 "%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n", 876 "%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
879 c->name, sg_size, i, sg_count); 877 c->name, sg_size, i, sg_count);
880 rcode = -ENOMEM; 878 rcode = -ENOMEM;
881 goto sg_list_cleanup; 879 goto sg_list_cleanup;
882 } 880 }
883 sg_list[sg_index++] = p; // sglist indexed with input frame, not our internal frame. 881 sg_index++;
884 /* Copy in the user's SG buffer if necessary */ 882 /* Copy in the user's SG buffer if necessary */
885 if (sg[i]. 883 if (sg[i].
886 flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR */ ) { 884 flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR */ ) {
887 // TODO 64bit fix 885 // TODO 64bit fix
888 if (copy_from_user 886 if (copy_from_user
889 (p, (void __user *)sg[i].addr_bus, 887 (p->virt, (void __user *)sg[i].addr_bus,
890 sg_size)) { 888 sg_size)) {
891 printk(KERN_DEBUG 889 printk(KERN_DEBUG
892 "%s: Could not copy SG buf %d FROM user\n", 890 "%s: Could not copy SG buf %d FROM user\n",
@@ -895,8 +893,7 @@ static int i2o_cfg_passthru(unsigned long arg)
895 goto sg_list_cleanup; 893 goto sg_list_cleanup;
896 } 894 }
897 } 895 }
898 //TODO 64bit fix 896 sg[i].addr_bus = p->phys;
899 sg[i].addr_bus = virt_to_bus(p);
900 } 897 }
901 } 898 }
902 899
@@ -908,7 +905,7 @@ static int i2o_cfg_passthru(unsigned long arg)
908 } 905 }
909 906
910 if (sg_offset) { 907 if (sg_offset) {
911 u32 rmsg[128]; 908 u32 rmsg[I2O_OUTBOUND_MSG_FRAME_SIZE];
912 /* Copy back the Scatter Gather buffers back to user space */ 909 /* Copy back the Scatter Gather buffers back to user space */
913 u32 j; 910 u32 j;
914 // TODO 64bit fix 911 // TODO 64bit fix
@@ -942,11 +939,11 @@ static int i2o_cfg_passthru(unsigned long arg)
942 sg_size = sg[j].flag_count & 0xffffff; 939 sg_size = sg[j].flag_count & 0xffffff;
943 // TODO 64bit fix 940 // TODO 64bit fix
944 if (copy_to_user 941 if (copy_to_user
945 ((void __user *)sg[j].addr_bus, sg_list[j], 942 ((void __user *)sg[j].addr_bus, sg_list[j].virt,
946 sg_size)) { 943 sg_size)) {
947 printk(KERN_WARNING 944 printk(KERN_WARNING
948 "%s: Could not copy %p TO user %x\n", 945 "%s: Could not copy %p TO user %x\n",
949 c->name, sg_list[j], 946 c->name, sg_list[j].virt,
950 sg[j].addr_bus); 947 sg[j].addr_bus);
951 rcode = -EFAULT; 948 rcode = -EFAULT;
952 goto sg_list_cleanup; 949 goto sg_list_cleanup;
@@ -973,7 +970,7 @@ sg_list_cleanup:
973 } 970 }
974 971
975 for (i = 0; i < sg_index; i++) 972 for (i = 0; i < sg_index; i++)
976 kfree(sg_list[i]); 973 i2o_dma_free(&c->pdev->dev, &sg_list[i]);
977 974
978cleanup: 975cleanup:
979 kfree(reply); 976 kfree(reply);
diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c
index da715e11c1b2..be2b5926d26c 100644
--- a/drivers/message/i2o/iop.c
+++ b/drivers/message/i2o/iop.c
@@ -1004,7 +1004,7 @@ static int i2o_hrt_get(struct i2o_controller *c)
1004 1004
1005 size = hrt->num_entries * hrt->entry_len << 2; 1005 size = hrt->num_entries * hrt->entry_len << 2;
1006 if (size > c->hrt.len) { 1006 if (size > c->hrt.len) {
1007 if (i2o_dma_realloc(dev, &c->hrt, size, GFP_KERNEL)) 1007 if (i2o_dma_realloc(dev, &c->hrt, size))
1008 return -ENOMEM; 1008 return -ENOMEM;
1009 else 1009 else
1010 hrt = c->hrt.virt; 1010 hrt = c->hrt.virt;
diff --git a/drivers/message/i2o/memory.c b/drivers/message/i2o/memory.c
new file mode 100644
index 000000000000..f5cc95c564e2
--- /dev/null
+++ b/drivers/message/i2o/memory.c
@@ -0,0 +1,313 @@
1/*
2 * Functions to handle I2O memory
3 *
4 * Pulled from the inlines in i2o headers and uninlined
5 *
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/module.h>
14#include <linux/i2o.h>
15#include <linux/delay.h>
16#include <linux/string.h>
17#include <linux/slab.h>
18#include "core.h"
19
20/* Protects our 32/64bit mask switching */
21static DEFINE_MUTEX(mem_lock);
22
23/**
24 * i2o_sg_tablesize - Calculate the maximum number of elements in a SGL
25 * @c: I2O controller for which the calculation should be done
26 * @body_size: maximum body size used for message in 32-bit words.
27 *
28 * Return the maximum number of SG elements in a SG list.
29 */
30u16 i2o_sg_tablesize(struct i2o_controller *c, u16 body_size)
31{
32 i2o_status_block *sb = c->status_block.virt;
33 u16 sg_count =
34 (sb->inbound_frame_size - sizeof(struct i2o_message) / 4) -
35 body_size;
36
37 if (c->pae_support) {
38 /*
39 * for 64-bit a SG attribute element must be added and each
40 * SG element needs 12 bytes instead of 8.
41 */
42 sg_count -= 2;
43 sg_count /= 3;
44 } else
45 sg_count /= 2;
46
47 if (c->short_req && (sg_count > 8))
48 sg_count = 8;
49
50 return sg_count;
51}
52EXPORT_SYMBOL_GPL(i2o_sg_tablesize);
53
54
55/**
56 * i2o_dma_map_single - Map pointer to controller and fill in I2O message.
57 * @c: I2O controller
58 * @ptr: pointer to the data which should be mapped
59 * @size: size of data in bytes
60 * @direction: DMA_TO_DEVICE / DMA_FROM_DEVICE
61 * @sg_ptr: pointer to the SG list inside the I2O message
62 *
63 * This function does all necessary DMA handling and also writes the I2O
64 * SGL elements into the I2O message. For details on DMA handling see also
65 * dma_map_single(). The pointer sg_ptr will only be set to the end of the
66 * SG list if the allocation was successful.
67 *
68 * Returns DMA address which must be checked for failures using
69 * dma_mapping_error().
70 */
71dma_addr_t i2o_dma_map_single(struct i2o_controller *c, void *ptr,
72 size_t size,
73 enum dma_data_direction direction,
74 u32 ** sg_ptr)
75{
76 u32 sg_flags;
77 u32 *mptr = *sg_ptr;
78 dma_addr_t dma_addr;
79
80 switch (direction) {
81 case DMA_TO_DEVICE:
82 sg_flags = 0xd4000000;
83 break;
84 case DMA_FROM_DEVICE:
85 sg_flags = 0xd0000000;
86 break;
87 default:
88 return 0;
89 }
90
91 dma_addr = dma_map_single(&c->pdev->dev, ptr, size, direction);
92 if (!dma_mapping_error(&c->pdev->dev, dma_addr)) {
93#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
94 if ((sizeof(dma_addr_t) > 4) && c->pae_support) {
95 *mptr++ = cpu_to_le32(0x7C020002);
96 *mptr++ = cpu_to_le32(PAGE_SIZE);
97 }
98#endif
99
100 *mptr++ = cpu_to_le32(sg_flags | size);
101 *mptr++ = cpu_to_le32(i2o_dma_low(dma_addr));
102#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
103 if ((sizeof(dma_addr_t) > 4) && c->pae_support)
104 *mptr++ = cpu_to_le32(i2o_dma_high(dma_addr));
105#endif
106 *sg_ptr = mptr;
107 }
108 return dma_addr;
109}
110EXPORT_SYMBOL_GPL(i2o_dma_map_single);
111
112/**
113 * i2o_dma_map_sg - Map a SG List to controller and fill in I2O message.
114 * @c: I2O controller
115 * @sg: SG list to be mapped
116 * @sg_count: number of elements in the SG list
117 * @direction: DMA_TO_DEVICE / DMA_FROM_DEVICE
118 * @sg_ptr: pointer to the SG list inside the I2O message
119 *
120 * This function does all necessary DMA handling and also writes the I2O
121 * SGL elements into the I2O message. For details on DMA handling see also
122 * dma_map_sg(). The pointer sg_ptr will only be set to the end of the SG
123 * list if the allocation was successful.
124 *
125 * Returns 0 on failure or 1 on success.
126 */
127int i2o_dma_map_sg(struct i2o_controller *c, struct scatterlist *sg,
128 int sg_count, enum dma_data_direction direction, u32 ** sg_ptr)
129{
130 u32 sg_flags;
131 u32 *mptr = *sg_ptr;
132
133 switch (direction) {
134 case DMA_TO_DEVICE:
135 sg_flags = 0x14000000;
136 break;
137 case DMA_FROM_DEVICE:
138 sg_flags = 0x10000000;
139 break;
140 default:
141 return 0;
142 }
143
144 sg_count = dma_map_sg(&c->pdev->dev, sg, sg_count, direction);
145 if (!sg_count)
146 return 0;
147
148#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
149 if ((sizeof(dma_addr_t) > 4) && c->pae_support) {
150 *mptr++ = cpu_to_le32(0x7C020002);
151 *mptr++ = cpu_to_le32(PAGE_SIZE);
152 }
153#endif
154
155 while (sg_count-- > 0) {
156 if (!sg_count)
157 sg_flags |= 0xC0000000;
158 *mptr++ = cpu_to_le32(sg_flags | sg_dma_len(sg));
159 *mptr++ = cpu_to_le32(i2o_dma_low(sg_dma_address(sg)));
160#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
161 if ((sizeof(dma_addr_t) > 4) && c->pae_support)
162 *mptr++ = cpu_to_le32(i2o_dma_high(sg_dma_address(sg)));
163#endif
164 sg = sg_next(sg);
165 }
166 *sg_ptr = mptr;
167
168 return 1;
169}
170EXPORT_SYMBOL_GPL(i2o_dma_map_sg);
171
172/**
173 * i2o_dma_alloc - Allocate DMA memory
174 * @dev: struct device pointer to the PCI device of the I2O controller
175 * @addr: i2o_dma struct which should get the DMA buffer
176 * @len: length of the new DMA memory
177 *
178 * Allocate a coherent DMA memory and write the pointers into addr.
179 *
180 * Returns 0 on success or -ENOMEM on failure.
181 */
182int i2o_dma_alloc(struct device *dev, struct i2o_dma *addr, size_t len)
183{
184 struct pci_dev *pdev = to_pci_dev(dev);
185 int dma_64 = 0;
186
187 mutex_lock(&mem_lock);
188 if ((sizeof(dma_addr_t) > 4) && (pdev->dma_mask == DMA_64BIT_MASK)) {
189 dma_64 = 1;
190 if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
191 mutex_unlock(&mem_lock);
192 return -ENOMEM;
193 }
194 }
195
196 addr->virt = dma_alloc_coherent(dev, len, &addr->phys, GFP_KERNEL);
197
198 if ((sizeof(dma_addr_t) > 4) && dma_64)
199 if (pci_set_dma_mask(pdev, DMA_64BIT_MASK))
200 printk(KERN_WARNING "i2o: unable to set 64-bit DMA");
201 mutex_unlock(&mem_lock);
202
203 if (!addr->virt)
204 return -ENOMEM;
205
206 memset(addr->virt, 0, len);
207 addr->len = len;
208
209 return 0;
210}
211EXPORT_SYMBOL_GPL(i2o_dma_alloc);
212
213
214/**
215 * i2o_dma_free - Free DMA memory
216 * @dev: struct device pointer to the PCI device of the I2O controller
217 * @addr: i2o_dma struct which contains the DMA buffer
218 *
219 * Free a coherent DMA memory and set virtual address of addr to NULL.
220 */
221void i2o_dma_free(struct device *dev, struct i2o_dma *addr)
222{
223 if (addr->virt) {
224 if (addr->phys)
225 dma_free_coherent(dev, addr->len, addr->virt,
226 addr->phys);
227 else
228 kfree(addr->virt);
229 addr->virt = NULL;
230 }
231}
232EXPORT_SYMBOL_GPL(i2o_dma_free);
233
234
235/**
236 * i2o_dma_realloc - Realloc DMA memory
237 * @dev: struct device pointer to the PCI device of the I2O controller
238 * @addr: pointer to a i2o_dma struct DMA buffer
239 * @len: new length of memory
240 *
241 * If there was something allocated in the addr, free it first. If len > 0
242 * than try to allocate it and write the addresses back to the addr
243 * structure. If len == 0 set the virtual address to NULL.
244 *
245 * Returns the 0 on success or negative error code on failure.
246 */
247int i2o_dma_realloc(struct device *dev, struct i2o_dma *addr, size_t len)
248{
249 i2o_dma_free(dev, addr);
250
251 if (len)
252 return i2o_dma_alloc(dev, addr, len);
253
254 return 0;
255}
256EXPORT_SYMBOL_GPL(i2o_dma_realloc);
257
258/*
259 * i2o_pool_alloc - Allocate an slab cache and mempool
260 * @mempool: pointer to struct i2o_pool to write data into.
261 * @name: name which is used to identify cache
262 * @size: size of each object
263 * @min_nr: minimum number of objects
264 *
265 * First allocates a slab cache with name and size. Then allocates a
266 * mempool which uses the slab cache for allocation and freeing.
267 *
268 * Returns 0 on success or negative error code on failure.
269 */
270int i2o_pool_alloc(struct i2o_pool *pool, const char *name,
271 size_t size, int min_nr)
272{
273 pool->name = kmalloc(strlen(name) + 1, GFP_KERNEL);
274 if (!pool->name)
275 goto exit;
276 strcpy(pool->name, name);
277
278 pool->slab =
279 kmem_cache_create(pool->name, size, 0, SLAB_HWCACHE_ALIGN, NULL);
280 if (!pool->slab)
281 goto free_name;
282
283 pool->mempool = mempool_create_slab_pool(min_nr, pool->slab);
284 if (!pool->mempool)
285 goto free_slab;
286
287 return 0;
288
289free_slab:
290 kmem_cache_destroy(pool->slab);
291
292free_name:
293 kfree(pool->name);
294
295exit:
296 return -ENOMEM;
297}
298EXPORT_SYMBOL_GPL(i2o_pool_alloc);
299
300/*
301 * i2o_pool_free - Free slab cache and mempool again
302 * @mempool: pointer to struct i2o_pool which should be freed
303 *
304 * Note that you have to return all objects to the mempool again before
305 * calling i2o_pool_free().
306 */
307void i2o_pool_free(struct i2o_pool *pool)
308{
309 mempool_destroy(pool->mempool);
310 kmem_cache_destroy(pool->slab);
311 kfree(pool->name);
312};
313EXPORT_SYMBOL_GPL(i2o_pool_free);
diff --git a/drivers/message/i2o/pci.c b/drivers/message/i2o/pci.c
index 685a89547a51..610ef1204e68 100644
--- a/drivers/message/i2o/pci.c
+++ b/drivers/message/i2o/pci.c
@@ -186,31 +186,29 @@ static int __devinit i2o_pci_alloc(struct i2o_controller *c)
186 } 186 }
187 } 187 }
188 188
189 if (i2o_dma_alloc(dev, &c->status, 8, GFP_KERNEL)) { 189 if (i2o_dma_alloc(dev, &c->status, 8)) {
190 i2o_pci_free(c); 190 i2o_pci_free(c);
191 return -ENOMEM; 191 return -ENOMEM;
192 } 192 }
193 193
194 if (i2o_dma_alloc(dev, &c->hrt, sizeof(i2o_hrt), GFP_KERNEL)) { 194 if (i2o_dma_alloc(dev, &c->hrt, sizeof(i2o_hrt))) {
195 i2o_pci_free(c); 195 i2o_pci_free(c);
196 return -ENOMEM; 196 return -ENOMEM;
197 } 197 }
198 198
199 if (i2o_dma_alloc(dev, &c->dlct, 8192, GFP_KERNEL)) { 199 if (i2o_dma_alloc(dev, &c->dlct, 8192)) {
200 i2o_pci_free(c); 200 i2o_pci_free(c);
201 return -ENOMEM; 201 return -ENOMEM;
202 } 202 }
203 203
204 if (i2o_dma_alloc(dev, &c->status_block, sizeof(i2o_status_block), 204 if (i2o_dma_alloc(dev, &c->status_block, sizeof(i2o_status_block))) {
205 GFP_KERNEL)) {
206 i2o_pci_free(c); 205 i2o_pci_free(c);
207 return -ENOMEM; 206 return -ENOMEM;
208 } 207 }
209 208
210 if (i2o_dma_alloc 209 if (i2o_dma_alloc(dev, &c->out_queue,
211 (dev, &c->out_queue, 210 I2O_MAX_OUTBOUND_MSG_FRAMES * I2O_OUTBOUND_MSG_FRAME_SIZE *
212 I2O_MAX_OUTBOUND_MSG_FRAMES * I2O_OUTBOUND_MSG_FRAME_SIZE * 211 sizeof(u32))) {
213 sizeof(u32), GFP_KERNEL)) {
214 i2o_pci_free(c); 212 i2o_pci_free(c);
215 return -ENOMEM; 213 return -ENOMEM;
216 } 214 }
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index a726f3b01a6b..efd3aa08b88b 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -15,7 +15,7 @@ if MISC_DEVICES
15 15
16config ATMEL_PWM 16config ATMEL_PWM
17 tristate "Atmel AT32/AT91 PWM support" 17 tristate "Atmel AT32/AT91 PWM support"
18 depends on AVR32 || ARCH_AT91 18 depends on AVR32 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9
19 help 19 help
20 This option enables device driver support for the PWM channels 20 This option enables device driver support for the PWM channels
21 on certain Atmel prcoessors. Pulse Width Modulation is used for 21 on certain Atmel prcoessors. Pulse Width Modulation is used for
@@ -409,6 +409,7 @@ config EEEPC_LAPTOP
409 depends on BACKLIGHT_CLASS_DEVICE 409 depends on BACKLIGHT_CLASS_DEVICE
410 depends on HWMON 410 depends on HWMON
411 depends on EXPERIMENTAL 411 depends on EXPERIMENTAL
412 depends on RFKILL
412 ---help--- 413 ---help---
413 This driver supports the Fn-Fx keys on Eee PC laptops. 414 This driver supports the Fn-Fx keys on Eee PC laptops.
414 It also adds the ability to switch camera/wlan on/off. 415 It also adds the ability to switch camera/wlan on/off.
diff --git a/drivers/misc/hp-wmi.c b/drivers/misc/hp-wmi.c
index 6d407c2a4f91..5dabfb69ee53 100644
--- a/drivers/misc/hp-wmi.c
+++ b/drivers/misc/hp-wmi.c
@@ -309,7 +309,7 @@ static int hp_wmi_setkeycode(struct input_dev *dev, int scancode, int keycode)
309 return -EINVAL; 309 return -EINVAL;
310} 310}
311 311
312void hp_wmi_notify(u32 value, void *context) 312static void hp_wmi_notify(u32 value, void *context)
313{ 313{
314 struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL }; 314 struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
315 static struct key_entry *key; 315 static struct key_entry *key;
diff --git a/drivers/misc/sgi-gru/gru.h b/drivers/misc/sgi-gru/gru.h
index 40df7cb3f0a5..f93f03a9e6e9 100644
--- a/drivers/misc/sgi-gru/gru.h
+++ b/drivers/misc/sgi-gru/gru.h
@@ -30,9 +30,9 @@
30/* 30/*
31 * Size used to map GRU GSeg 31 * Size used to map GRU GSeg
32 */ 32 */
33#if defined CONFIG_IA64 33#if defined(CONFIG_IA64)
34#define GRU_GSEG_PAGESIZE (256 * 1024UL) 34#define GRU_GSEG_PAGESIZE (256 * 1024UL)
35#elif defined CONFIG_X86_64 35#elif defined(CONFIG_X86_64)
36#define GRU_GSEG_PAGESIZE (256 * 1024UL) /* ZZZ 2MB ??? */ 36#define GRU_GSEG_PAGESIZE (256 * 1024UL) /* ZZZ 2MB ??? */
37#else 37#else
38#error "Unsupported architecture" 38#error "Unsupported architecture"
diff --git a/drivers/misc/sgi-gru/gru_instructions.h b/drivers/misc/sgi-gru/gru_instructions.h
index 0dc36225c7c6..48762e7b98be 100644
--- a/drivers/misc/sgi-gru/gru_instructions.h
+++ b/drivers/misc/sgi-gru/gru_instructions.h
@@ -26,7 +26,7 @@
26 * Architecture dependent functions 26 * Architecture dependent functions
27 */ 27 */
28 28
29#if defined CONFIG_IA64 29#if defined(CONFIG_IA64)
30#include <linux/compiler.h> 30#include <linux/compiler.h>
31#include <asm/intrinsics.h> 31#include <asm/intrinsics.h>
32#define __flush_cache(p) ia64_fc(p) 32#define __flush_cache(p) ia64_fc(p)
@@ -36,7 +36,7 @@
36 barrier(); \ 36 barrier(); \
37 *((volatile int *)(p)) = v; /* force st.rel */ \ 37 *((volatile int *)(p)) = v; /* force st.rel */ \
38 } while (0) 38 } while (0)
39#elif defined CONFIG_X86_64 39#elif defined(CONFIG_X86_64)
40#define __flush_cache(p) clflush(p) 40#define __flush_cache(p) clflush(p)
41#define gru_ordered_store_int(p,v) \ 41#define gru_ordered_store_int(p,v) \
42 do { \ 42 do { \
@@ -299,6 +299,7 @@ static inline void gru_flush_cache(void *p)
299static inline void gru_start_instruction(struct gru_instruction *ins, int op32) 299static inline void gru_start_instruction(struct gru_instruction *ins, int op32)
300{ 300{
301 gru_ordered_store_int(ins, op32); 301 gru_ordered_store_int(ins, op32);
302 gru_flush_cache(ins);
302} 303}
303 304
304 305
@@ -604,8 +605,9 @@ static inline int gru_get_cb_substatus(void *cb)
604static inline int gru_check_status(void *cb) 605static inline int gru_check_status(void *cb)
605{ 606{
606 struct gru_control_block_status *cbs = (void *)cb; 607 struct gru_control_block_status *cbs = (void *)cb;
607 int ret = cbs->istatus; 608 int ret;
608 609
610 ret = cbs->istatus;
609 if (ret == CBS_CALL_OS) 611 if (ret == CBS_CALL_OS)
610 ret = gru_check_status_proc(cb); 612 ret = gru_check_status_proc(cb);
611 return ret; 613 return ret;
@@ -617,7 +619,7 @@ static inline int gru_check_status(void *cb)
617static inline int gru_wait(void *cb) 619static inline int gru_wait(void *cb)
618{ 620{
619 struct gru_control_block_status *cbs = (void *)cb; 621 struct gru_control_block_status *cbs = (void *)cb;
620 int ret = cbs->istatus;; 622 int ret = cbs->istatus;
621 623
622 if (ret != CBS_IDLE) 624 if (ret != CBS_IDLE)
623 ret = gru_wait_proc(cb); 625 ret = gru_wait_proc(cb);
diff --git a/drivers/misc/sgi-gru/grufault.c b/drivers/misc/sgi-gru/grufault.c
index 3d33015bbf31..8c389d606c30 100644
--- a/drivers/misc/sgi-gru/grufault.c
+++ b/drivers/misc/sgi-gru/grufault.c
@@ -214,12 +214,14 @@ static int non_atomic_pte_lookup(struct vm_area_struct *vma,
214} 214}
215 215
216/* 216/*
217 *
218 * atomic_pte_lookup 217 * atomic_pte_lookup
219 * 218 *
220 * Convert a user virtual address to a physical address 219 * Convert a user virtual address to a physical address
221 * Only supports Intel large pages (2MB only) on x86_64. 220 * Only supports Intel large pages (2MB only) on x86_64.
222 * ZZZ - hugepage support is incomplete 221 * ZZZ - hugepage support is incomplete
222 *
223 * NOTE: mmap_sem is already held on entry to this function. This
224 * guarantees existence of the page tables.
223 */ 225 */
224static int atomic_pte_lookup(struct vm_area_struct *vma, unsigned long vaddr, 226static int atomic_pte_lookup(struct vm_area_struct *vma, unsigned long vaddr,
225 int write, unsigned long *paddr, int *pageshift) 227 int write, unsigned long *paddr, int *pageshift)
@@ -229,9 +231,6 @@ static int atomic_pte_lookup(struct vm_area_struct *vma, unsigned long vaddr,
229 pud_t *pudp; 231 pud_t *pudp;
230 pte_t pte; 232 pte_t pte;
231 233
232 WARN_ON(irqs_disabled()); /* ZZZ debug */
233
234 local_irq_disable();
235 pgdp = pgd_offset(vma->vm_mm, vaddr); 234 pgdp = pgd_offset(vma->vm_mm, vaddr);
236 if (unlikely(pgd_none(*pgdp))) 235 if (unlikely(pgd_none(*pgdp)))
237 goto err; 236 goto err;
@@ -250,8 +249,6 @@ static int atomic_pte_lookup(struct vm_area_struct *vma, unsigned long vaddr,
250#endif 249#endif
251 pte = *pte_offset_kernel(pmdp, vaddr); 250 pte = *pte_offset_kernel(pmdp, vaddr);
252 251
253 local_irq_enable();
254
255 if (unlikely(!pte_present(pte) || 252 if (unlikely(!pte_present(pte) ||
256 (write && (!pte_write(pte) || !pte_dirty(pte))))) 253 (write && (!pte_write(pte) || !pte_dirty(pte)))))
257 return 1; 254 return 1;
@@ -324,6 +321,7 @@ static int gru_try_dropin(struct gru_thread_state *gts,
324 * Atomic lookup is faster & usually works even if called in non-atomic 321 * Atomic lookup is faster & usually works even if called in non-atomic
325 * context. 322 * context.
326 */ 323 */
324 rmb(); /* Must/check ms_range_active before loading PTEs */
327 ret = atomic_pte_lookup(vma, vaddr, write, &paddr, &pageshift); 325 ret = atomic_pte_lookup(vma, vaddr, write, &paddr, &pageshift);
328 if (ret) { 326 if (ret) {
329 if (!cb) 327 if (!cb)
@@ -543,6 +541,7 @@ int gru_get_exception_detail(unsigned long arg)
543 ucbnum = get_cb_number((void *)excdet.cb); 541 ucbnum = get_cb_number((void *)excdet.cb);
544 cbrnum = thread_cbr_number(gts, ucbnum); 542 cbrnum = thread_cbr_number(gts, ucbnum);
545 cbe = get_cbe_by_index(gts->ts_gru, cbrnum); 543 cbe = get_cbe_by_index(gts->ts_gru, cbrnum);
544 prefetchw(cbe); /* Harmless on hardware, required for emulator */
546 excdet.opc = cbe->opccpy; 545 excdet.opc = cbe->opccpy;
547 excdet.exopc = cbe->exopccpy; 546 excdet.exopc = cbe->exopccpy;
548 excdet.ecause = cbe->ecause; 547 excdet.ecause = cbe->ecause;
diff --git a/drivers/misc/sgi-gru/grufile.c b/drivers/misc/sgi-gru/grufile.c
index d61cee796efd..5c027b6b4e5a 100644
--- a/drivers/misc/sgi-gru/grufile.c
+++ b/drivers/misc/sgi-gru/grufile.c
@@ -113,7 +113,7 @@ static int gru_file_mmap(struct file *file, struct vm_area_struct *vma)
113 return -EPERM; 113 return -EPERM;
114 114
115 if (vma->vm_start & (GRU_GSEG_PAGESIZE - 1) || 115 if (vma->vm_start & (GRU_GSEG_PAGESIZE - 1) ||
116 vma->vm_end & (GRU_GSEG_PAGESIZE - 1)) 116 vma->vm_end & (GRU_GSEG_PAGESIZE - 1))
117 return -EINVAL; 117 return -EINVAL;
118 118
119 vma->vm_flags |= 119 vma->vm_flags |=
@@ -398,6 +398,12 @@ static int __init gru_init(void)
398 irq = get_base_irq(); 398 irq = get_base_irq();
399 for (chip = 0; chip < GRU_CHIPLETS_PER_BLADE; chip++) { 399 for (chip = 0; chip < GRU_CHIPLETS_PER_BLADE; chip++) {
400 ret = request_irq(irq + chip, gru_intr, 0, id, NULL); 400 ret = request_irq(irq + chip, gru_intr, 0, id, NULL);
401 /* TODO: fix irq handling on x86. For now ignore failures because
402 * interrupts are not required & not yet fully supported */
403 if (ret) {
404 printk("!!!WARNING: GRU ignoring request failure!!!\n");
405 ret = 0;
406 }
401 if (ret) { 407 if (ret) {
402 printk(KERN_ERR "%s: request_irq failed\n", 408 printk(KERN_ERR "%s: request_irq failed\n",
403 GRU_DRIVER_ID_STR); 409 GRU_DRIVER_ID_STR);
diff --git a/drivers/misc/sgi-gru/gruhandles.h b/drivers/misc/sgi-gru/gruhandles.h
index d16031d62673..b63018d60fe1 100644
--- a/drivers/misc/sgi-gru/gruhandles.h
+++ b/drivers/misc/sgi-gru/gruhandles.h
@@ -91,12 +91,7 @@
91#define GSEGPOFF(h) ((h) & (GRU_SIZE - 1)) 91#define GSEGPOFF(h) ((h) & (GRU_SIZE - 1))
92 92
93/* Convert an arbitrary handle address to the beginning of the GRU segment */ 93/* Convert an arbitrary handle address to the beginning of the GRU segment */
94#ifndef __PLUGIN__
95#define GRUBASE(h) ((void *)((unsigned long)(h) & ~(GRU_SIZE - 1))) 94#define GRUBASE(h) ((void *)((unsigned long)(h) & ~(GRU_SIZE - 1)))
96#else
97extern void *gmu_grubase(void *h);
98#define GRUBASE(h) gmu_grubase(h)
99#endif
100 95
101/* General addressing macros. */ 96/* General addressing macros. */
102static inline void *get_gseg_base_address(void *base, int ctxnum) 97static inline void *get_gseg_base_address(void *base, int ctxnum)
diff --git a/drivers/misc/sgi-gru/grukservices.c b/drivers/misc/sgi-gru/grukservices.c
index dfd49af0fe18..880c55dfb662 100644
--- a/drivers/misc/sgi-gru/grukservices.c
+++ b/drivers/misc/sgi-gru/grukservices.c
@@ -122,6 +122,7 @@ int gru_get_cb_exception_detail(void *cb,
122 struct gru_control_block_extended *cbe; 122 struct gru_control_block_extended *cbe;
123 123
124 cbe = get_cbe(GRUBASE(cb), get_cb_number(cb)); 124 cbe = get_cbe(GRUBASE(cb), get_cb_number(cb));
125 prefetchw(cbe); /* Harmless on hardware, required for emulator */
125 excdet->opc = cbe->opccpy; 126 excdet->opc = cbe->opccpy;
126 excdet->exopc = cbe->exopccpy; 127 excdet->exopc = cbe->exopccpy;
127 excdet->ecause = cbe->ecause; 128 excdet->ecause = cbe->ecause;
@@ -466,7 +467,7 @@ int gru_send_message_gpa(unsigned long mq, void *mesg, unsigned int bytes)
466 STAT(mesq_send); 467 STAT(mesq_send);
467 BUG_ON(bytes < sizeof(int) || bytes > 2 * GRU_CACHE_LINE_BYTES); 468 BUG_ON(bytes < sizeof(int) || bytes > 2 * GRU_CACHE_LINE_BYTES);
468 469
469 clines = (bytes + GRU_CACHE_LINE_BYTES - 1) / GRU_CACHE_LINE_BYTES; 470 clines = DIV_ROUND_UP(bytes, GRU_CACHE_LINE_BYTES);
470 if (gru_get_cpu_resources(bytes, &cb, &dsr)) 471 if (gru_get_cpu_resources(bytes, &cb, &dsr))
471 return MQE_BUG_NO_RESOURCES; 472 return MQE_BUG_NO_RESOURCES;
472 memcpy(dsr, mesg, bytes); 473 memcpy(dsr, mesg, bytes);
diff --git a/drivers/misc/sgi-gru/grumain.c b/drivers/misc/sgi-gru/grumain.c
index 0eeb8dddd2f5..e11e1ac50900 100644
--- a/drivers/misc/sgi-gru/grumain.c
+++ b/drivers/misc/sgi-gru/grumain.c
@@ -432,29 +432,35 @@ static inline long gru_copy_handle(void *d, void *s)
432 return GRU_HANDLE_BYTES; 432 return GRU_HANDLE_BYTES;
433} 433}
434 434
435/* rewrite in assembly & use lots of prefetch */ 435static void gru_prefetch_context(void *gseg, void *cb, void *cbe, unsigned long cbrmap,
436static void gru_load_context_data(void *save, void *grubase, int ctxnum, 436 unsigned long length)
437 unsigned long cbrmap, unsigned long dsrmap)
438{ 437{
439 void *gseg, *cb, *cbe;
440 unsigned long length;
441 int i, scr; 438 int i, scr;
442 439
443 gseg = grubase + ctxnum * GRU_GSEG_STRIDE;
444 length = hweight64(dsrmap) * GRU_DSR_AU_BYTES;
445 prefetch_data(gseg + GRU_DS_BASE, length / GRU_CACHE_LINE_BYTES, 440 prefetch_data(gseg + GRU_DS_BASE, length / GRU_CACHE_LINE_BYTES,
446 GRU_CACHE_LINE_BYTES); 441 GRU_CACHE_LINE_BYTES);
447 442
448 cb = gseg + GRU_CB_BASE;
449 cbe = grubase + GRU_CBE_BASE;
450 for_each_cbr_in_allocation_map(i, &cbrmap, scr) { 443 for_each_cbr_in_allocation_map(i, &cbrmap, scr) {
451 prefetch_data(cb, 1, GRU_CACHE_LINE_BYTES); 444 prefetch_data(cb, 1, GRU_CACHE_LINE_BYTES);
452 prefetch_data(cbe + i * GRU_HANDLE_STRIDE, 1, 445 prefetch_data(cbe + i * GRU_HANDLE_STRIDE, 1,
453 GRU_CACHE_LINE_BYTES); 446 GRU_CACHE_LINE_BYTES);
454 cb += GRU_HANDLE_STRIDE; 447 cb += GRU_HANDLE_STRIDE;
455 } 448 }
449}
450
451static void gru_load_context_data(void *save, void *grubase, int ctxnum,
452 unsigned long cbrmap, unsigned long dsrmap)
453{
454 void *gseg, *cb, *cbe;
455 unsigned long length;
456 int i, scr;
456 457
458 gseg = grubase + ctxnum * GRU_GSEG_STRIDE;
457 cb = gseg + GRU_CB_BASE; 459 cb = gseg + GRU_CB_BASE;
460 cbe = grubase + GRU_CBE_BASE;
461 length = hweight64(dsrmap) * GRU_DSR_AU_BYTES;
462 gru_prefetch_context(gseg, cb, cbe, cbrmap, length);
463
458 for_each_cbr_in_allocation_map(i, &cbrmap, scr) { 464 for_each_cbr_in_allocation_map(i, &cbrmap, scr) {
459 save += gru_copy_handle(cb, save); 465 save += gru_copy_handle(cb, save);
460 save += gru_copy_handle(cbe + i * GRU_HANDLE_STRIDE, save); 466 save += gru_copy_handle(cbe + i * GRU_HANDLE_STRIDE, save);
@@ -472,15 +478,16 @@ static void gru_unload_context_data(void *save, void *grubase, int ctxnum,
472 int i, scr; 478 int i, scr;
473 479
474 gseg = grubase + ctxnum * GRU_GSEG_STRIDE; 480 gseg = grubase + ctxnum * GRU_GSEG_STRIDE;
475
476 cb = gseg + GRU_CB_BASE; 481 cb = gseg + GRU_CB_BASE;
477 cbe = grubase + GRU_CBE_BASE; 482 cbe = grubase + GRU_CBE_BASE;
483 length = hweight64(dsrmap) * GRU_DSR_AU_BYTES;
484 gru_prefetch_context(gseg, cb, cbe, cbrmap, length);
485
478 for_each_cbr_in_allocation_map(i, &cbrmap, scr) { 486 for_each_cbr_in_allocation_map(i, &cbrmap, scr) {
479 save += gru_copy_handle(save, cb); 487 save += gru_copy_handle(save, cb);
480 save += gru_copy_handle(save, cbe + i * GRU_HANDLE_STRIDE); 488 save += gru_copy_handle(save, cbe + i * GRU_HANDLE_STRIDE);
481 cb += GRU_HANDLE_STRIDE; 489 cb += GRU_HANDLE_STRIDE;
482 } 490 }
483 length = hweight64(dsrmap) * GRU_DSR_AU_BYTES;
484 memcpy(save, gseg + GRU_DS_BASE, length); 491 memcpy(save, gseg + GRU_DS_BASE, length);
485} 492}
486 493
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index c16028872bbb..1b9fc3c6b875 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -172,7 +172,7 @@ struct mmc_omap_host {
172 struct omap_mmc_platform_data *pdata; 172 struct omap_mmc_platform_data *pdata;
173}; 173};
174 174
175void mmc_omap_fclk_offdelay(struct mmc_omap_slot *slot) 175static void mmc_omap_fclk_offdelay(struct mmc_omap_slot *slot)
176{ 176{
177 unsigned long tick_ns; 177 unsigned long tick_ns;
178 178
@@ -182,7 +182,7 @@ void mmc_omap_fclk_offdelay(struct mmc_omap_slot *slot)
182 } 182 }
183} 183}
184 184
185void mmc_omap_fclk_enable(struct mmc_omap_host *host, unsigned int enable) 185static void mmc_omap_fclk_enable(struct mmc_omap_host *host, unsigned int enable)
186{ 186{
187 unsigned long flags; 187 unsigned long flags;
188 188
@@ -1455,7 +1455,9 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
1455 1455
1456 host->irq = irq; 1456 host->irq = irq;
1457 host->phys_base = host->mem_res->start; 1457 host->phys_base = host->mem_res->start;
1458 host->virt_base = (void __iomem *) IO_ADDRESS(host->phys_base); 1458 host->virt_base = ioremap(res->start, res->end - res->start + 1);
1459 if (!host->virt_base)
1460 goto err_ioremap;
1459 1461
1460 if (cpu_is_omap24xx()) { 1462 if (cpu_is_omap24xx()) {
1461 host->iclk = clk_get(&pdev->dev, "mmc_ick"); 1463 host->iclk = clk_get(&pdev->dev, "mmc_ick");
@@ -1510,6 +1512,8 @@ err_free_iclk:
1510 clk_put(host->iclk); 1512 clk_put(host->iclk);
1511 } 1513 }
1512err_free_mmc_host: 1514err_free_mmc_host:
1515 iounmap(host->virt_base);
1516err_ioremap:
1513 kfree(host); 1517 kfree(host);
1514err_free_mem_region: 1518err_free_mem_region:
1515 release_mem_region(res->start, res->end - res->start + 1); 1519 release_mem_region(res->start, res->end - res->start + 1);
@@ -1536,6 +1540,7 @@ static int mmc_omap_remove(struct platform_device *pdev)
1536 if (host->fclk && !IS_ERR(host->fclk)) 1540 if (host->fclk && !IS_ERR(host->fclk))
1537 clk_put(host->fclk); 1541 clk_put(host->fclk);
1538 1542
1543 iounmap(host->virt_base);
1539 release_mem_region(pdev->resource[0].start, 1544 release_mem_region(pdev->resource[0].start,
1540 pdev->resource[0].end - pdev->resource[0].start + 1); 1545 pdev->resource[0].end - pdev->resource[0].start + 1);
1541 1546
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index edb90b58a9b1..9a06dc93ee0d 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -564,10 +564,8 @@ int parse_mtd_partitions(struct mtd_info *master, const char **types,
564 564
565 for ( ; ret <= 0 && *types; types++) { 565 for ( ; ret <= 0 && *types; types++) {
566 parser = get_partition_parser(*types); 566 parser = get_partition_parser(*types);
567#ifdef CONFIG_KMOD
568 if (!parser && !request_module("%s", *types)) 567 if (!parser && !request_module("%s", *types))
569 parser = get_partition_parser(*types); 568 parser = get_partition_parser(*types);
570#endif
571 if (!parser) { 569 if (!parser) {
572 printk(KERN_NOTICE "%s partition parsing not available\n", 570 printk(KERN_NOTICE "%s partition parsing not available\n",
573 *types); 571 *types);
diff --git a/drivers/mtd/nand/ams-delta.c b/drivers/mtd/nand/ams-delta.c
index 26d42987971f..782994ead0e8 100644
--- a/drivers/mtd/nand/ams-delta.c
+++ b/drivers/mtd/nand/ams-delta.c
@@ -145,7 +145,7 @@ static void ams_delta_hwcontrol(struct mtd_info *mtd, int cmd,
145 145
146static int ams_delta_nand_ready(struct mtd_info *mtd) 146static int ams_delta_nand_ready(struct mtd_info *mtd)
147{ 147{
148 return omap_get_gpio_datain(AMS_DELTA_GPIO_PIN_NAND_RB); 148 return gpio_get_value(AMS_DELTA_GPIO_PIN_NAND_RB);
149} 149}
150 150
151/* 151/*
@@ -185,7 +185,7 @@ static int __init ams_delta_init(void)
185 this->read_buf = ams_delta_read_buf; 185 this->read_buf = ams_delta_read_buf;
186 this->verify_buf = ams_delta_verify_buf; 186 this->verify_buf = ams_delta_verify_buf;
187 this->cmd_ctrl = ams_delta_hwcontrol; 187 this->cmd_ctrl = ams_delta_hwcontrol;
188 if (!omap_request_gpio(AMS_DELTA_GPIO_PIN_NAND_RB)) { 188 if (gpio_request(AMS_DELTA_GPIO_PIN_NAND_RB, "nand_rdy") == 0) {
189 this->dev_ready = ams_delta_nand_ready; 189 this->dev_ready = ams_delta_nand_ready;
190 } else { 190 } else {
191 this->dev_ready = NULL; 191 this->dev_ready = NULL;
diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c
index b9d097c9f6bb..3a7bc524af33 100644
--- a/drivers/net/3c509.c
+++ b/drivers/net/3c509.c
@@ -40,7 +40,7 @@
40 v1.14 10/15/97 Avoided waiting..discard message for fast machines -djb 40 v1.14 10/15/97 Avoided waiting..discard message for fast machines -djb
41 v1.15 1/31/98 Faster recovery for Tx errors. -djb 41 v1.15 1/31/98 Faster recovery for Tx errors. -djb
42 v1.16 2/3/98 Different ID port handling to avoid sound cards. -djb 42 v1.16 2/3/98 Different ID port handling to avoid sound cards. -djb
43 v1.18 12Mar2001 Andrew Morton <andrewm@uow.edu.au> 43 v1.18 12Mar2001 Andrew Morton
44 - Avoid bogus detect of 3c590's (Andrzej Krzysztofowicz) 44 - Avoid bogus detect of 3c590's (Andrzej Krzysztofowicz)
45 - Reviewed against 1.18 from scyld.com 45 - Reviewed against 1.18 from scyld.com
46 v1.18a 17Nov2001 Jeff Garzik <jgarzik@pobox.com> 46 v1.18a 17Nov2001 Jeff Garzik <jgarzik@pobox.com>
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c
index a28de8182802..7107620f615d 100644
--- a/drivers/net/cs89x0.c
+++ b/drivers/net/cs89x0.c
@@ -36,8 +36,7 @@
36 36
37 Alan Cox : Removed 1.2 support, added 2.1 extra counters. 37 Alan Cox : Removed 1.2 support, added 2.1 extra counters.
38 38
39 Andrew Morton : andrewm@uow.edu.au 39 Andrew Morton : Kernel 2.3.48
40 : Kernel 2.3.48
41 : Handle kmalloc() failures 40 : Handle kmalloc() failures
42 : Other resource allocation fixes 41 : Other resource allocation fixes
43 : Add SMP locks 42 : Add SMP locks
@@ -49,7 +48,7 @@
49 : Fixed an out-of-mem bug in dma_rx() 48 : Fixed an out-of-mem bug in dma_rx()
50 : Updated Documentation/networking/cs89x0.txt 49 : Updated Documentation/networking/cs89x0.txt
51 50
52 Andrew Morton : andrewm@uow.edu.au / Kernel 2.3.99-pre1 51 Andrew Morton : Kernel 2.3.99-pre1
53 : Use skb_reserve to longword align IP header (two places) 52 : Use skb_reserve to longword align IP header (two places)
54 : Remove a delay loop from dma_rx() 53 : Remove a delay loop from dma_rx()
55 : Replace '100' with HZ 54 : Replace '100' with HZ
@@ -57,11 +56,11 @@
57 : Added 'cs89x0_dma=N' kernel boot option 56 : Added 'cs89x0_dma=N' kernel boot option
58 : Correctly initialise lp->lock in non-module compile 57 : Correctly initialise lp->lock in non-module compile
59 58
60 Andrew Morton : andrewm@uow.edu.au / Kernel 2.3.99-pre4-1 59 Andrew Morton : Kernel 2.3.99-pre4-1
61 : MOD_INC/DEC race fix (see 60 : MOD_INC/DEC race fix (see
62 : http://www.uwsg.indiana.edu/hypermail/linux/kernel/0003.3/1532.html) 61 : http://www.uwsg.indiana.edu/hypermail/linux/kernel/0003.3/1532.html)
63 62
64 Andrew Morton : andrewm@uow.edu.au / Kernel 2.4.0-test7-pre2 63 Andrew Morton : Kernel 2.4.0-test7-pre2
65 : Enhanced EEPROM support to cover more devices, 64 : Enhanced EEPROM support to cover more devices,
66 : abstracted IRQ mapping to support CONFIG_ARCH_CLPS7500 arch 65 : abstracted IRQ mapping to support CONFIG_ARCH_CLPS7500 arch
67 : (Jason Gunthorpe <jgg@ualberta.ca>) 66 : (Jason Gunthorpe <jgg@ualberta.ca>)
@@ -156,7 +155,7 @@
156#include "cs89x0.h" 155#include "cs89x0.h"
157 156
158static char version[] __initdata = 157static char version[] __initdata =
159"cs89x0.c: v2.4.3-pre1 Russell Nelson <nelson@crynwr.com>, Andrew Morton <andrewm@uow.edu.au>\n"; 158"cs89x0.c: v2.4.3-pre1 Russell Nelson <nelson@crynwr.com>, Andrew Morton\n";
160 159
161#define DRV_NAME "cs89x0" 160#define DRV_NAME "cs89x0"
162 161
@@ -1877,7 +1876,7 @@ MODULE_PARM_DESC(dmasize , "(ignored)");
1877MODULE_PARM_DESC(use_dma , "(ignored)"); 1876MODULE_PARM_DESC(use_dma , "(ignored)");
1878#endif 1877#endif
1879 1878
1880MODULE_AUTHOR("Mike Cruse, Russwll Nelson <nelson@crynwr.com>, Andrew Morton <andrewm@uow.edu.au>"); 1879MODULE_AUTHOR("Mike Cruse, Russwll Nelson <nelson@crynwr.com>, Andrew Morton");
1881MODULE_LICENSE("GPL"); 1880MODULE_LICENSE("GPL");
1882 1881
1883 1882
diff --git a/drivers/net/irda/sir_dongle.c b/drivers/net/irda/sir_dongle.c
index 36030241f7a9..2a9930e6e2af 100644
--- a/drivers/net/irda/sir_dongle.c
+++ b/drivers/net/irda/sir_dongle.c
@@ -67,9 +67,7 @@ int sirdev_get_dongle(struct sir_dev *dev, IRDA_DONGLE type)
67 const struct dongle_driver *drv = NULL; 67 const struct dongle_driver *drv = NULL;
68 int err = -EINVAL; 68 int err = -EINVAL;
69 69
70#ifdef CONFIG_KMOD
71 request_module("irda-dongle-%d", type); 70 request_module("irda-dongle-%d", type);
72#endif
73 71
74 if (dev->dongle_drv != NULL) 72 if (dev->dongle_drv != NULL)
75 return -EBUSY; 73 return -EBUSY;
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 03d027c68879..7e857e938adb 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -2127,13 +2127,9 @@ ppp_set_compress(struct ppp *ppp, unsigned long arg)
2127 || ccp_option[1] < 2 || ccp_option[1] > data.length) 2127 || ccp_option[1] < 2 || ccp_option[1] > data.length)
2128 goto out; 2128 goto out;
2129 2129
2130 cp = find_compressor(ccp_option[0]); 2130 cp = try_then_request_module(
2131#ifdef CONFIG_KMOD 2131 find_compressor(ccp_option[0]),
2132 if (!cp) { 2132 "ppp-compress-%d", ccp_option[0]);
2133 request_module("ppp-compress-%d", ccp_option[0]);
2134 cp = find_compressor(ccp_option[0]);
2135 }
2136#endif /* CONFIG_KMOD */
2137 if (!cp) 2133 if (!cp)
2138 goto out; 2134 goto out;
2139 2135
diff --git a/drivers/net/pppox.c b/drivers/net/pppox.c
index c6898c1fc54d..03aecc97fb45 100644
--- a/drivers/net/pppox.c
+++ b/drivers/net/pppox.c
@@ -115,13 +115,8 @@ static int pppox_create(struct net *net, struct socket *sock, int protocol)
115 goto out; 115 goto out;
116 116
117 rc = -EPROTONOSUPPORT; 117 rc = -EPROTONOSUPPORT;
118#ifdef CONFIG_KMOD 118 if (!pppox_protos[protocol])
119 if (!pppox_protos[protocol]) { 119 request_module("pppox-proto-%d", protocol);
120 char buffer[32];
121 sprintf(buffer, "pppox-proto-%d", protocol);
122 request_module(buffer);
123 }
124#endif
125 if (!pppox_protos[protocol] || 120 if (!pppox_protos[protocol] ||
126 !try_module_get(pppox_protos[protocol]->owner)) 121 !try_module_get(pppox_protos[protocol]->owner))
127 goto out; 122 goto out;
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index 74726990d59e..f05f584ab7bc 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -1640,6 +1640,11 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
1640 return ret; 1640 return ret;
1641} 1641}
1642 1642
1643static int ath9k_no_fragmentation(struct ieee80211_hw *hw, u32 value)
1644{
1645 return -EOPNOTSUPP;
1646}
1647
1643static struct ieee80211_ops ath9k_ops = { 1648static struct ieee80211_ops ath9k_ops = {
1644 .tx = ath9k_tx, 1649 .tx = ath9k_tx,
1645 .start = ath9k_start, 1650 .start = ath9k_start,
@@ -1664,7 +1669,8 @@ static struct ieee80211_ops ath9k_ops = {
1664 .get_tsf = ath9k_get_tsf, 1669 .get_tsf = ath9k_get_tsf,
1665 .reset_tsf = ath9k_reset_tsf, 1670 .reset_tsf = ath9k_reset_tsf,
1666 .tx_last_beacon = NULL, 1671 .tx_last_beacon = NULL,
1667 .ampdu_action = ath9k_ampdu_action 1672 .ampdu_action = ath9k_ampdu_action,
1673 .set_frag_threshold = ath9k_no_fragmentation,
1668}; 1674};
1669 1675
1670static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) 1676static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index f6003e7996af..5155b8a760a7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -833,12 +833,12 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
833 switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) { 833 switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
834 case CSR_HW_REV_TYPE_5100: 834 case CSR_HW_REV_TYPE_5100:
835 case CSR_HW_REV_TYPE_5300: 835 case CSR_HW_REV_TYPE_5300:
836 /* 5X00 wants in Celsius */ 836 case CSR_HW_REV_TYPE_5350:
837 /* 5X00 and 5350 wants in Celsius */
837 priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD; 838 priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD;
838 break; 839 break;
839 case CSR_HW_REV_TYPE_5150: 840 case CSR_HW_REV_TYPE_5150:
840 case CSR_HW_REV_TYPE_5350: 841 /* 5150 wants in Kelvin */
841 /* 5X50 wants in Kelvin */
842 priv->hw_params.ct_kill_threshold = 842 priv->hw_params.ct_kill_threshold =
843 CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD); 843 CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD);
844 break; 844 break;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 93944de923ca..e2a58e477036 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -2422,7 +2422,7 @@ static void rs_free_sta(void *priv_r, struct ieee80211_sta *sta,
2422 void *priv_sta) 2422 void *priv_sta)
2423{ 2423{
2424 struct iwl_lq_sta *lq_sta = priv_sta; 2424 struct iwl_lq_sta *lq_sta = priv_sta;
2425 struct iwl_priv *priv = priv_r; 2425 struct iwl_priv *priv __maybe_unused = priv_r;
2426 2426
2427 IWL_DEBUG_RATE("enter\n"); 2427 IWL_DEBUG_RATE("enter\n");
2428 kfree(lq_sta); 2428 kfree(lq_sta);
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index a912fb68c099..297696de2da0 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -823,7 +823,9 @@ int lbs_update_channel(struct lbs_private *priv)
823int lbs_set_channel(struct lbs_private *priv, u8 channel) 823int lbs_set_channel(struct lbs_private *priv, u8 channel)
824{ 824{
825 struct cmd_ds_802_11_rf_channel cmd; 825 struct cmd_ds_802_11_rf_channel cmd;
826#ifdef DEBUG
826 u8 old_channel = priv->curbssparams.channel; 827 u8 old_channel = priv->curbssparams.channel;
828#endif
827 int ret = 0; 829 int ret = 0;
828 830
829 lbs_deb_enter(LBS_DEB_CMD); 831 lbs_deb_enter(LBS_DEB_CMD);
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
index e585684e59a0..6fcf2bda7cdf 100644
--- a/drivers/net/wireless/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco_cs.c
@@ -378,6 +378,7 @@ static int orinoco_cs_resume(struct pcmcia_device *link)
378 struct orinoco_private *priv = netdev_priv(dev); 378 struct orinoco_private *priv = netdev_priv(dev);
379 struct orinoco_pccard *card = priv->card; 379 struct orinoco_pccard *card = priv->card;
380 int err = 0; 380 int err = 0;
381 unsigned long flags;
381 382
382 if (! test_bit(0, &card->hard_reset_in_progress)) { 383 if (! test_bit(0, &card->hard_reset_in_progress)) {
383 err = orinoco_reinit_firmware(dev); 384 err = orinoco_reinit_firmware(dev);
@@ -387,7 +388,7 @@ static int orinoco_cs_resume(struct pcmcia_device *link)
387 return -EIO; 388 return -EIO;
388 } 389 }
389 390
390 spin_lock(&priv->lock); 391 spin_lock_irqsave(&priv->lock, flags);
391 392
392 netif_device_attach(dev); 393 netif_device_attach(dev);
393 priv->hw_unavailable--; 394 priv->hw_unavailable--;
@@ -399,7 +400,7 @@ static int orinoco_cs_resume(struct pcmcia_device *link)
399 dev->name, err); 400 dev->name, err);
400 } 401 }
401 402
402 spin_unlock(&priv->lock); 403 spin_unlock_irqrestore(&priv->lock, flags);
403 } 404 }
404 405
405 return err; 406 return err;
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index 1994aa199d37..117c7d3a52b0 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -479,7 +479,6 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
479 printk(KERN_ERR "p54: eeprom parse failed!\n"); 479 printk(KERN_ERR "p54: eeprom parse failed!\n");
480 return err; 480 return err;
481} 481}
482EXPORT_SYMBOL_GPL(p54_parse_eeprom);
483 482
484static int p54_rssi_to_dbm(struct ieee80211_hw *dev, int rssi) 483static int p54_rssi_to_dbm(struct ieee80211_hw *dev, int rssi)
485{ 484{
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index 1912f5e9a0a9..75d749bccb0d 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -39,6 +39,7 @@ static struct usb_device_id p54u_table[] __devinitdata = {
39 {USB_DEVICE(0x0846, 0x4200)}, /* Netgear WG121 */ 39 {USB_DEVICE(0x0846, 0x4200)}, /* Netgear WG121 */
40 {USB_DEVICE(0x0846, 0x4210)}, /* Netgear WG121 the second ? */ 40 {USB_DEVICE(0x0846, 0x4210)}, /* Netgear WG121 the second ? */
41 {USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */ 41 {USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */
42 {USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */
42 {USB_DEVICE(0x0cde, 0x0006)}, /* Medion 40900, Roper Europe */ 43 {USB_DEVICE(0x0cde, 0x0006)}, /* Medion 40900, Roper Europe */
43 {USB_DEVICE(0x124a, 0x4023)}, /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */ 44 {USB_DEVICE(0x124a, 0x4023)}, /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */
44 {USB_DEVICE(0x1915, 0x2234)}, /* Linksys WUSB54G OEM */ 45 {USB_DEVICE(0x1915, 0x2234)}, /* Linksys WUSB54G OEM */
@@ -63,8 +64,8 @@ static struct usb_device_id p54u_table[] __devinitdata = {
63 {USB_DEVICE(0x0cde, 0x0006)}, /* Medion MD40900 */ 64 {USB_DEVICE(0x0cde, 0x0006)}, /* Medion MD40900 */
64 {USB_DEVICE(0x0cde, 0x0008)}, /* Sagem XG703A */ 65 {USB_DEVICE(0x0cde, 0x0008)}, /* Sagem XG703A */
65 {USB_DEVICE(0x0d8e, 0x3762)}, /* DLink DWL-G120 Cohiba */ 66 {USB_DEVICE(0x0d8e, 0x3762)}, /* DLink DWL-G120 Cohiba */
66 {USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */
67 {USB_DEVICE(0x124a, 0x4025)}, /* IOGear GWU513 (GW3887IK chip) */ 67 {USB_DEVICE(0x124a, 0x4025)}, /* IOGear GWU513 (GW3887IK chip) */
68 {USB_DEVICE(0x1260, 0xee22)}, /* SMC 2862W-G version 2 */
68 {USB_DEVICE(0x13b1, 0x000a)}, /* Linksys WUSB54G ver 2 */ 69 {USB_DEVICE(0x13b1, 0x000a)}, /* Linksys WUSB54G ver 2 */
69 {USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */ 70 {USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */
70 {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */ 71 {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 1676ac484790..451d410ecdae 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -374,7 +374,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
374 struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); 374 struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
375 struct txentry_desc txdesc; 375 struct txentry_desc txdesc;
376 struct skb_frame_desc *skbdesc; 376 struct skb_frame_desc *skbdesc;
377 unsigned int iv_len; 377 unsigned int iv_len = 0;
378 378
379 if (unlikely(rt2x00queue_full(queue))) 379 if (unlikely(rt2x00queue_full(queue)))
380 return -EINVAL; 380 return -EINVAL;
@@ -395,6 +395,9 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
395 entry->skb = skb; 395 entry->skb = skb;
396 rt2x00queue_create_tx_descriptor(entry, &txdesc); 396 rt2x00queue_create_tx_descriptor(entry, &txdesc);
397 397
398 if (IEEE80211_SKB_CB(skb)->control.hw_key != NULL)
399 iv_len = IEEE80211_SKB_CB(skb)->control.hw_key->iv_len;
400
398 /* 401 /*
399 * All information is retreived from the skb->cb array, 402 * All information is retreived from the skb->cb array,
400 * now we should claim ownership of the driver part of that 403 * now we should claim ownership of the driver part of that
@@ -410,9 +413,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
410 * the frame so we can provide it to the driver seperately. 413 * the frame so we can provide it to the driver seperately.
411 */ 414 */
412 if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) && 415 if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) &&
413 !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags) && 416 !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) {
414 (IEEE80211_SKB_CB(skb)->control.hw_key != NULL)) {
415 iv_len = IEEE80211_SKB_CB(skb)->control.hw_key->iv_len;
416 rt2x00crypto_tx_remove_iv(skb, iv_len); 417 rt2x00crypto_tx_remove_iv(skb, iv_len);
417 } 418 }
418 419
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c
index e9902613e2ee..431e3c78bf27 100644
--- a/drivers/net/wireless/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl8187_dev.c
@@ -33,10 +33,13 @@ MODULE_LICENSE("GPL");
33static struct usb_device_id rtl8187_table[] __devinitdata = { 33static struct usb_device_id rtl8187_table[] __devinitdata = {
34 /* Asus */ 34 /* Asus */
35 {USB_DEVICE(0x0b05, 0x171d), .driver_info = DEVICE_RTL8187}, 35 {USB_DEVICE(0x0b05, 0x171d), .driver_info = DEVICE_RTL8187},
36 /* Belkin */
37 {USB_DEVICE(0x050d, 0x705e), .driver_info = DEVICE_RTL8187B},
36 /* Realtek */ 38 /* Realtek */
37 {USB_DEVICE(0x0bda, 0x8187), .driver_info = DEVICE_RTL8187}, 39 {USB_DEVICE(0x0bda, 0x8187), .driver_info = DEVICE_RTL8187},
38 {USB_DEVICE(0x0bda, 0x8189), .driver_info = DEVICE_RTL8187B}, 40 {USB_DEVICE(0x0bda, 0x8189), .driver_info = DEVICE_RTL8187B},
39 {USB_DEVICE(0x0bda, 0x8197), .driver_info = DEVICE_RTL8187B}, 41 {USB_DEVICE(0x0bda, 0x8197), .driver_info = DEVICE_RTL8187B},
42 {USB_DEVICE(0x0bda, 0x8198), .driver_info = DEVICE_RTL8187B},
40 /* Netgear */ 43 /* Netgear */
41 {USB_DEVICE(0x0846, 0x6100), .driver_info = DEVICE_RTL8187}, 44 {USB_DEVICE(0x0846, 0x6100), .driver_info = DEVICE_RTL8187},
42 {USB_DEVICE(0x0846, 0x6a00), .driver_info = DEVICE_RTL8187}, 45 {USB_DEVICE(0x0846, 0x6a00), .driver_info = DEVICE_RTL8187},
diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c
index b0c71c3be467..852789ad34b3 100644
--- a/drivers/net/wireless/spectrum_cs.c
+++ b/drivers/net/wireless/spectrum_cs.c
@@ -426,10 +426,11 @@ spectrum_cs_suspend(struct pcmcia_device *link)
426{ 426{
427 struct net_device *dev = link->priv; 427 struct net_device *dev = link->priv;
428 struct orinoco_private *priv = netdev_priv(dev); 428 struct orinoco_private *priv = netdev_priv(dev);
429 unsigned long flags;
429 int err = 0; 430 int err = 0;
430 431
431 /* Mark the device as stopped, to block IO until later */ 432 /* Mark the device as stopped, to block IO until later */
432 spin_lock(&priv->lock); 433 spin_lock_irqsave(&priv->lock, flags);
433 434
434 err = __orinoco_down(dev); 435 err = __orinoco_down(dev);
435 if (err) 436 if (err)
@@ -439,7 +440,7 @@ spectrum_cs_suspend(struct pcmcia_device *link)
439 netif_device_detach(dev); 440 netif_device_detach(dev);
440 priv->hw_unavailable++; 441 priv->hw_unavailable++;
441 442
442 spin_unlock(&priv->lock); 443 spin_unlock_irqrestore(&priv->lock, flags);
443 444
444 return err; 445 return err;
445} 446}
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 3c3dd403f5dd..5c7a87e38951 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -471,7 +471,7 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev)
471 unsigned int offset = offset_in_page(data); 471 unsigned int offset = offset_in_page(data);
472 unsigned int len = skb_headlen(skb); 472 unsigned int len = skb_headlen(skb);
473 473
474 frags += (offset + len + PAGE_SIZE - 1) / PAGE_SIZE; 474 frags += DIV_ROUND_UP(offset + len, PAGE_SIZE);
475 if (unlikely(frags > MAX_SKB_FRAGS + 1)) { 475 if (unlikely(frags > MAX_SKB_FRAGS + 1)) {
476 printk(KERN_ALERT "xennet: skb rides the rocket: %d frags\n", 476 printk(KERN_ALERT "xennet: skb rides the rocket: %d frags\n",
477 frags); 477 frags);
diff --git a/drivers/nubus/nubus.c b/drivers/nubus/nubus.c
index 2f047e573d86..f5f75844954c 100644
--- a/drivers/nubus/nubus.c
+++ b/drivers/nubus/nubus.c
@@ -126,7 +126,7 @@ static void nubus_advance(unsigned char **ptr, int len, int map)
126 { 126 {
127 while(not_useful(p,map)) 127 while(not_useful(p,map))
128 p++; 128 p++;
129 p++; 129 p++;
130 len--; 130 len--;
131 } 131 }
132 *ptr = p; 132 *ptr = p;
diff --git a/drivers/parport/ChangeLog b/drivers/parport/ChangeLog
index db717c1d62a5..8565bbbeb6ec 100644
--- a/drivers/parport/ChangeLog
+++ b/drivers/parport/ChangeLog
@@ -311,7 +311,7 @@
311 * ieee1284_ops.c (parport_ieee1284_read_nibble): Reset nAutoFd 311 * ieee1284_ops.c (parport_ieee1284_read_nibble): Reset nAutoFd
312 on timeout. Matches 2.2.x behaviour. 312 on timeout. Matches 2.2.x behaviour.
313 313
3142001-03-02 Andrew Morton <andrewm@uow.edu.au> 3142001-03-02 Andrew Morton
315 315
316 * parport_pc.c (registered_parport): New static variable. 316 * parport_pc.c (registered_parport): New static variable.
317 (parport_pc_find_ports): Set it when we register PCI driver. 317 (parport_pc_find_ports): Set it when we register PCI driver.
diff --git a/drivers/parport/ieee1284.c b/drivers/parport/ieee1284.c
index e97059415ab4..ac2a805ac7ea 100644
--- a/drivers/parport/ieee1284.c
+++ b/drivers/parport/ieee1284.c
@@ -1,4 +1,4 @@
1/* $Id: parport_ieee1284.c,v 1.4 1997/10/19 21:37:21 philip Exp $ 1/*
2 * IEEE-1284 implementation for parport. 2 * IEEE-1284 implementation for parport.
3 * 3 *
4 * Authors: Phil Blundell <philb@gnu.org> 4 * Authors: Phil Blundell <philb@gnu.org>
diff --git a/drivers/parport/probe.c b/drivers/parport/probe.c
index cd565bb4e1a9..0f6550719bcf 100644
--- a/drivers/parport/probe.c
+++ b/drivers/parport/probe.c
@@ -1,4 +1,4 @@
1/* $Id: parport_probe.c,v 1.1 1999/07/03 08:56:17 davem Exp $ 1/*
2 * Parallel port device probing code 2 * Parallel port device probing code
3 * 3 *
4 * Authors: Carsten Gross, carsten@sol.wohnheim.uni-ulm.de 4 * Authors: Carsten Gross, carsten@sol.wohnheim.uni-ulm.de
diff --git a/drivers/parport/share.c b/drivers/parport/share.c
index a8a62bbbb576..0ebca450ed29 100644
--- a/drivers/parport/share.c
+++ b/drivers/parport/share.c
@@ -1,4 +1,4 @@
1/* $Id: parport_share.c,v 1.15 1998/01/11 12:06:17 philip Exp $ 1/*
2 * Parallel-port resource manager code. 2 * Parallel-port resource manager code.
3 * 3 *
4 * Authors: David Campbell <campbell@tirian.che.curtin.edu.au> 4 * Authors: David Campbell <campbell@tirian.che.curtin.edu.au>
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index 74d1c906c5d6..b46c60b72708 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -64,10 +64,11 @@ sa1100_cs-$(CONFIG_SA1100_SHANNON) += sa1100_shannon.o
64sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o 64sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o
65 65
66pxa2xx_lubbock_cs-y += pxa2xx_lubbock.o sa1111_generic.o 66pxa2xx_lubbock_cs-y += pxa2xx_lubbock.o sa1111_generic.o
67pxa2xx_cm_x2xx_cs-y += pxa2xx_cm_x2xx.o pxa2xx_cm_x255.o pxa2xx_cm_x270.o
67pxa2xx-obj-$(CONFIG_ARCH_LUBBOCK) += pxa2xx_lubbock_cs.o 68pxa2xx-obj-$(CONFIG_ARCH_LUBBOCK) += pxa2xx_lubbock_cs.o
68pxa2xx-obj-$(CONFIG_MACH_MAINSTONE) += pxa2xx_mainstone.o 69pxa2xx-obj-$(CONFIG_MACH_MAINSTONE) += pxa2xx_mainstone.o
69pxa2xx-obj-$(CONFIG_PXA_SHARPSL) += pxa2xx_sharpsl.o 70pxa2xx-obj-$(CONFIG_PXA_SHARPSL) += pxa2xx_sharpsl.o
70pxa2xx-obj-$(CONFIG_MACH_ARMCORE) += pxa2xx_cm_x2xx.o pxa2xx_cm_x255.o pxa2xx_cm_x270.o 71pxa2xx-obj-$(CONFIG_MACH_ARMCORE) += pxa2xx_cm_x2xx_cs.o
71pxa2xx-obj-$(CONFIG_ARCH_VIPER) += pxa2xx_viper.o 72pxa2xx-obj-$(CONFIG_ARCH_VIPER) += pxa2xx_viper.o
72pxa2xx-obj-$(CONFIG_TRIZEPS_PCMCIA) += pxa2xx_trizeps.o 73pxa2xx-obj-$(CONFIG_TRIZEPS_PCMCIA) += pxa2xx_trizeps.o
73pxa2xx-obj-$(CONFIG_MACH_PALMTX) += pxa2xx_palmtx.o 74pxa2xx-obj-$(CONFIG_MACH_PALMTX) += pxa2xx_palmtx.o
diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h
index 3532984a9cab..3b8b9d3cb03d 100644
--- a/drivers/pnp/base.h
+++ b/drivers/pnp/base.h
@@ -147,7 +147,7 @@ char *pnp_resource_type_name(struct resource *res);
147void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc); 147void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc);
148 148
149void pnp_free_resources(struct pnp_dev *dev); 149void pnp_free_resources(struct pnp_dev *dev);
150int pnp_resource_type(struct resource *res); 150unsigned long pnp_resource_type(struct resource *res);
151 151
152struct pnp_resource { 152struct pnp_resource {
153 struct list_head list; 153 struct list_head list;
diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c
index 7d65da821229..817fe626e15b 100644
--- a/drivers/pnp/core.c
+++ b/drivers/pnp/core.c
@@ -210,7 +210,6 @@ void __pnp_remove_device(struct pnp_dev *dev)
210 210
211static int __init pnp_init(void) 211static int __init pnp_init(void)
212{ 212{
213 printk(KERN_INFO "Linux Plug and Play Support v0.97 (c) Adam Belay\n");
214 return bus_register(&pnp_bus_type); 213 return bus_register(&pnp_bus_type);
215} 214}
216 215
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c
index 0bdf9b8a5e58..d15e2b77af88 100644
--- a/drivers/pnp/quirks.c
+++ b/drivers/pnp/quirks.c
@@ -245,7 +245,7 @@ static void quirk_system_pci_resources(struct pnp_dev *dev)
245 */ 245 */
246 for_each_pci_dev(pdev) { 246 for_each_pci_dev(pdev) {
247 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { 247 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
248 unsigned int type; 248 unsigned long type;
249 249
250 type = pci_resource_flags(pdev, i) & 250 type = pci_resource_flags(pdev, i) &
251 (IORESOURCE_IO | IORESOURCE_MEM); 251 (IORESOURCE_IO | IORESOURCE_MEM);
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index 4cfe3a1efdfb..dbae23acdd5b 100644
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -467,14 +467,14 @@ int pnp_check_dma(struct pnp_dev *dev, struct resource *res)
467#endif 467#endif
468} 468}
469 469
470int pnp_resource_type(struct resource *res) 470unsigned long pnp_resource_type(struct resource *res)
471{ 471{
472 return res->flags & (IORESOURCE_IO | IORESOURCE_MEM | 472 return res->flags & (IORESOURCE_IO | IORESOURCE_MEM |
473 IORESOURCE_IRQ | IORESOURCE_DMA); 473 IORESOURCE_IRQ | IORESOURCE_DMA);
474} 474}
475 475
476struct resource *pnp_get_resource(struct pnp_dev *dev, 476struct resource *pnp_get_resource(struct pnp_dev *dev,
477 unsigned int type, unsigned int num) 477 unsigned long type, unsigned int num)
478{ 478{
479 struct pnp_resource *pnp_res; 479 struct pnp_resource *pnp_res;
480 struct resource *res; 480 struct resource *res;
diff --git a/drivers/power/olpc_battery.c b/drivers/power/olpc_battery.c
index 32570af3c5c9..5fbca2681baa 100644
--- a/drivers/power/olpc_battery.c
+++ b/drivers/power/olpc_battery.c
@@ -205,9 +205,9 @@ static int olpc_bat_get_property(struct power_supply *psy,
205 union power_supply_propval *val) 205 union power_supply_propval *val)
206{ 206{
207 int ret = 0; 207 int ret = 0;
208 int16_t ec_word; 208 __be16 ec_word;
209 uint8_t ec_byte; 209 uint8_t ec_byte;
210 uint64_t ser_buf; 210 __be64 ser_buf;
211 211
212 ret = olpc_ec_cmd(EC_BAT_STATUS, NULL, 0, &ec_byte, 1); 212 ret = olpc_ec_cmd(EC_BAT_STATUS, NULL, 0, &ec_byte, 1);
213 if (ret) 213 if (ret)
@@ -257,16 +257,14 @@ static int olpc_bat_get_property(struct power_supply *psy,
257 if (ret) 257 if (ret)
258 return ret; 258 return ret;
259 259
260 ec_word = be16_to_cpu(ec_word); 260 val->intval = (int)be16_to_cpu(ec_word) * 9760L / 32;
261 val->intval = ec_word * 9760L / 32;
262 break; 261 break;
263 case POWER_SUPPLY_PROP_CURRENT_AVG: 262 case POWER_SUPPLY_PROP_CURRENT_AVG:
264 ret = olpc_ec_cmd(EC_BAT_CURRENT, NULL, 0, (void *)&ec_word, 2); 263 ret = olpc_ec_cmd(EC_BAT_CURRENT, NULL, 0, (void *)&ec_word, 2);
265 if (ret) 264 if (ret)
266 return ret; 265 return ret;
267 266
268 ec_word = be16_to_cpu(ec_word); 267 val->intval = (int)be16_to_cpu(ec_word) * 15625L / 120;
269 val->intval = ec_word * 15625L / 120;
270 break; 268 break;
271 case POWER_SUPPLY_PROP_CAPACITY: 269 case POWER_SUPPLY_PROP_CAPACITY:
272 ret = olpc_ec_cmd(EC_BAT_SOC, NULL, 0, &ec_byte, 1); 270 ret = olpc_ec_cmd(EC_BAT_SOC, NULL, 0, &ec_byte, 1);
@@ -278,24 +276,22 @@ static int olpc_bat_get_property(struct power_supply *psy,
278 ret = olpc_ec_cmd(EC_BAT_TEMP, NULL, 0, (void *)&ec_word, 2); 276 ret = olpc_ec_cmd(EC_BAT_TEMP, NULL, 0, (void *)&ec_word, 2);
279 if (ret) 277 if (ret)
280 return ret; 278 return ret;
281 ec_word = be16_to_cpu(ec_word); 279
282 val->intval = ec_word * 100 / 256; 280 val->intval = (int)be16_to_cpu(ec_word) * 100 / 256;
283 break; 281 break;
284 case POWER_SUPPLY_PROP_TEMP_AMBIENT: 282 case POWER_SUPPLY_PROP_TEMP_AMBIENT:
285 ret = olpc_ec_cmd(EC_AMB_TEMP, NULL, 0, (void *)&ec_word, 2); 283 ret = olpc_ec_cmd(EC_AMB_TEMP, NULL, 0, (void *)&ec_word, 2);
286 if (ret) 284 if (ret)
287 return ret; 285 return ret;
288 286
289 ec_word = be16_to_cpu(ec_word); 287 val->intval = (int)be16_to_cpu(ec_word) * 100 / 256;
290 val->intval = ec_word * 100 / 256;
291 break; 288 break;
292 case POWER_SUPPLY_PROP_CHARGE_COUNTER: 289 case POWER_SUPPLY_PROP_CHARGE_COUNTER:
293 ret = olpc_ec_cmd(EC_BAT_ACR, NULL, 0, (void *)&ec_word, 2); 290 ret = olpc_ec_cmd(EC_BAT_ACR, NULL, 0, (void *)&ec_word, 2);
294 if (ret) 291 if (ret)
295 return ret; 292 return ret;
296 293
297 ec_word = be16_to_cpu(ec_word); 294 val->intval = (int)be16_to_cpu(ec_word) * 6250 / 15;
298 val->intval = ec_word * 6250 / 15;
299 break; 295 break;
300 case POWER_SUPPLY_PROP_SERIAL_NUMBER: 296 case POWER_SUPPLY_PROP_SERIAL_NUMBER:
301 ret = olpc_ec_cmd(EC_BAT_SERIAL, NULL, 0, (void *)&ser_buf, 8); 297 ret = olpc_ec_cmd(EC_BAT_SERIAL, NULL, 0, (void *)&ser_buf, 8);
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index f3d7fd3406a6..f660ef3e5b29 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -220,22 +220,22 @@ config RTC_DRV_PCF8583
220 will be called rtc-pcf8583. 220 will be called rtc-pcf8583.
221 221
222config RTC_DRV_M41T80 222config RTC_DRV_M41T80
223 tristate "ST M41T80/81/82/83/84/85/87" 223 tristate "ST M41T65/M41T80/81/82/83/84/85/87"
224 help 224 help
225 If you say Y here you will get support for the 225 If you say Y here you will get support for the ST M41T60
226 ST M41T80 RTC chips series. Currently following chips are 226 and M41T80 RTC chips series. Currently, the following chips are
227 supported: M41T80, M41T81, M41T82, M41T83, M41ST84, M41ST85 227 supported: M41T65, M41T80, M41T81, M41T82, M41T83, M41ST84,
228 and M41ST87. 228 M41ST85, and M41ST87.
229 229
230 This driver can also be built as a module. If so, the module 230 This driver can also be built as a module. If so, the module
231 will be called rtc-m41t80. 231 will be called rtc-m41t80.
232 232
233config RTC_DRV_M41T80_WDT 233config RTC_DRV_M41T80_WDT
234 bool "ST M41T80 series RTC watchdog timer" 234 bool "ST M41T65/M41T80 series RTC watchdog timer"
235 depends on RTC_DRV_M41T80 235 depends on RTC_DRV_M41T80
236 help 236 help
237 If you say Y here you will get support for the 237 If you say Y here you will get support for the
238 watchdog timer in ST M41T80 RTC chips series. 238 watchdog timer in the ST M41T60 and M41T80 RTC chips series.
239 239
240config RTC_DRV_TWL92330 240config RTC_DRV_TWL92330
241 boolean "TI TWL92330/Menelaus" 241 boolean "TI TWL92330/Menelaus"
@@ -319,6 +319,15 @@ config RTC_DRV_RS5C348
319 This driver can also be built as a module. If so, the module 319 This driver can also be built as a module. If so, the module
320 will be called rtc-rs5c348. 320 will be called rtc-rs5c348.
321 321
322config RTC_DRV_DS3234
323 tristate "Maxim/Dallas DS3234"
324 help
325 If you say yes here you get support for the
326 Maxim/Dallas DS3234 SPI RTC chip.
327
328 This driver can also be built as a module. If so, the module
329 will be called rtc-ds3234.
330
322endif # SPI_MASTER 331endif # SPI_MASTER
323 332
324comment "Platform RTC drivers" 333comment "Platform RTC drivers"
@@ -603,7 +612,7 @@ config RTC_DRV_RS5C313
603 612
604config RTC_DRV_PPC 613config RTC_DRV_PPC
605 tristate "PowerPC machine dependent RTC support" 614 tristate "PowerPC machine dependent RTC support"
606 depends on PPC_MERGE 615 depends on PPC
607 help 616 help
608 The PowerPC kernel has machine-specific functions for accessing 617 The PowerPC kernel has machine-specific functions for accessing
609 the RTC. This exposes that functionality through the generic RTC 618 the RTC. This exposes that functionality through the generic RTC
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 37a71b727262..d05928b3ca94 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_RTC_DRV_DS1511) += rtc-ds1511.o
32obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o 32obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o
33obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o 33obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o
34obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o 34obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o
35obj-$(CONFIG_RTC_DRV_DS3234) += rtc-ds3234.o
35obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o 36obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o
36obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o 37obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o
37obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o 38obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o
diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c
index 4e888cc8be5b..37082616482b 100644
--- a/drivers/rtc/rtc-at91rm9200.c
+++ b/drivers/rtc/rtc-at91rm9200.c
@@ -29,10 +29,10 @@
29#include <linux/completion.h> 29#include <linux/completion.h>
30 30
31#include <asm/uaccess.h> 31#include <asm/uaccess.h>
32
32#include <mach/at91_rtc.h> 33#include <mach/at91_rtc.h>
33 34
34 35
35#define AT91_RTC_FREQ 1
36#define AT91_RTC_EPOCH 1900UL /* just like arch/arm/common/rtctime.c */ 36#define AT91_RTC_EPOCH 1900UL /* just like arch/arm/common/rtctime.c */
37 37
38static DECLARE_COMPLETION(at91_rtc_updated); 38static DECLARE_COMPLETION(at91_rtc_updated);
@@ -228,8 +228,6 @@ static int at91_rtc_proc(struct device *dev, struct seq_file *seq)
228 (imr & AT91_RTC_ACKUPD) ? "yes" : "no"); 228 (imr & AT91_RTC_ACKUPD) ? "yes" : "no");
229 seq_printf(seq, "periodic_IRQ\t: %s\n", 229 seq_printf(seq, "periodic_IRQ\t: %s\n",
230 (imr & AT91_RTC_SECEV) ? "yes" : "no"); 230 (imr & AT91_RTC_SECEV) ? "yes" : "no");
231 seq_printf(seq, "periodic_freq\t: %ld\n",
232 (unsigned long) AT91_RTC_FREQ);
233 231
234 return 0; 232 return 0;
235} 233}
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c
index 52e2743b04ec..079e9ed907e0 100644
--- a/drivers/rtc/rtc-dev.c
+++ b/drivers/rtc/rtc-dev.c
@@ -432,9 +432,15 @@ static int rtc_dev_release(struct inode *inode, struct file *file)
432{ 432{
433 struct rtc_device *rtc = file->private_data; 433 struct rtc_device *rtc = file->private_data;
434 434
435#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL 435 /* We shut down the repeating IRQs that userspace enabled,
436 clear_uie(rtc); 436 * since nothing is listening to them.
437#endif 437 * - Update (UIE) ... currently only managed through ioctls
438 * - Periodic (PIE) ... also used through rtc_*() interface calls
439 *
440 * Leave the alarm alone; it may be set to trigger a system wakeup
441 * later, or be used by kernel code, and is a one-shot event anyway.
442 */
443 rtc_dev_ioctl(file, RTC_UIE_OFF, 0);
438 rtc_irq_set_state(rtc, NULL, 0); 444 rtc_irq_set_state(rtc, NULL, 0);
439 445
440 if (rtc->ops->release) 446 if (rtc->ops->release)
diff --git a/drivers/rtc/rtc-ds1286.c b/drivers/rtc/rtc-ds1286.c
index 4b4c1b6a4187..4fcb16bbff4a 100644
--- a/drivers/rtc/rtc-ds1286.c
+++ b/drivers/rtc/rtc-ds1286.c
@@ -17,6 +17,7 @@
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/bcd.h> 18#include <linux/bcd.h>
19#include <linux/ds1286.h> 19#include <linux/ds1286.h>
20#include <linux/io.h>
20 21
21#define DRV_VERSION "1.0" 22#define DRV_VERSION "1.0"
22 23
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index bbf97e65202a..4fcf0734a6ef 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -23,10 +23,6 @@
23 * to have set the chip up as a clock (turning on the oscillator and 23 * to have set the chip up as a clock (turning on the oscillator and
24 * setting the date and time), Linux can ignore the non-clock features. 24 * setting the date and time), Linux can ignore the non-clock features.
25 * That's a natural job for a factory or repair bench. 25 * That's a natural job for a factory or repair bench.
26 *
27 * This is currently a simple no-alarms driver. If your board has the
28 * alarm irq wired up on a ds1337 or ds1339, and you want to use that,
29 * then look at the rtc-rs5c372 driver for code to steal...
30 */ 26 */
31enum ds_type { 27enum ds_type {
32 ds_1307, 28 ds_1307,
@@ -67,6 +63,7 @@ enum ds_type {
67# define DS1307_BIT_RS0 0x01 63# define DS1307_BIT_RS0 0x01
68#define DS1337_REG_CONTROL 0x0e 64#define DS1337_REG_CONTROL 0x0e
69# define DS1337_BIT_nEOSC 0x80 65# define DS1337_BIT_nEOSC 0x80
66# define DS1339_BIT_BBSQI 0x20
70# define DS1337_BIT_RS2 0x10 67# define DS1337_BIT_RS2 0x10
71# define DS1337_BIT_RS1 0x08 68# define DS1337_BIT_RS1 0x08
72# define DS1337_BIT_INTCN 0x04 69# define DS1337_BIT_INTCN 0x04
@@ -83,19 +80,22 @@ enum ds_type {
83# define DS1337_BIT_OSF 0x80 80# define DS1337_BIT_OSF 0x80
84# define DS1337_BIT_A2I 0x02 81# define DS1337_BIT_A2I 0x02
85# define DS1337_BIT_A1I 0x01 82# define DS1337_BIT_A1I 0x01
83#define DS1339_REG_ALARM1_SECS 0x07
86#define DS1339_REG_TRICKLE 0x10 84#define DS1339_REG_TRICKLE 0x10
87 85
88 86
89 87
90struct ds1307 { 88struct ds1307 {
91 u8 reg_addr; 89 u8 reg_addr;
92 bool has_nvram; 90 u8 regs[11];
93 u8 regs[8];
94 enum ds_type type; 91 enum ds_type type;
92 unsigned long flags;
93#define HAS_NVRAM 0 /* bit 0 == sysfs file active */
94#define HAS_ALARM 1 /* bit 1 == irq claimed */
95 struct i2c_msg msg[2]; 95 struct i2c_msg msg[2];
96 struct i2c_client *client; 96 struct i2c_client *client;
97 struct i2c_client dev;
98 struct rtc_device *rtc; 97 struct rtc_device *rtc;
98 struct work_struct work;
99}; 99};
100 100
101struct chip_desc { 101struct chip_desc {
@@ -132,12 +132,79 @@ static const struct i2c_device_id ds1307_id[] = {
132}; 132};
133MODULE_DEVICE_TABLE(i2c, ds1307_id); 133MODULE_DEVICE_TABLE(i2c, ds1307_id);
134 134
135/*----------------------------------------------------------------------*/
136
137/*
138 * The IRQ logic includes a "real" handler running in IRQ context just
139 * long enough to schedule this workqueue entry. We need a task context
140 * to talk to the RTC, since I2C I/O calls require that; and disable the
141 * IRQ until we clear its status on the chip, so that this handler can
142 * work with any type of triggering (not just falling edge).
143 *
144 * The ds1337 and ds1339 both have two alarms, but we only use the first
145 * one (with a "seconds" field). For ds1337 we expect nINTA is our alarm
146 * signal; ds1339 chips have only one alarm signal.
147 */
148static void ds1307_work(struct work_struct *work)
149{
150 struct ds1307 *ds1307;
151 struct i2c_client *client;
152 struct mutex *lock;
153 int stat, control;
154
155 ds1307 = container_of(work, struct ds1307, work);
156 client = ds1307->client;
157 lock = &ds1307->rtc->ops_lock;
158
159 mutex_lock(lock);
160 stat = i2c_smbus_read_byte_data(client, DS1337_REG_STATUS);
161 if (stat < 0)
162 goto out;
163
164 if (stat & DS1337_BIT_A1I) {
165 stat &= ~DS1337_BIT_A1I;
166 i2c_smbus_write_byte_data(client, DS1337_REG_STATUS, stat);
167
168 control = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL);
169 if (control < 0)
170 goto out;
171
172 control &= ~DS1337_BIT_A1IE;
173 i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL, control);
174
175 /* rtc_update_irq() assumes that it is called
176 * from IRQ-disabled context.
177 */
178 local_irq_disable();
179 rtc_update_irq(ds1307->rtc, 1, RTC_AF | RTC_IRQF);
180 local_irq_enable();
181 }
182
183out:
184 if (test_bit(HAS_ALARM, &ds1307->flags))
185 enable_irq(client->irq);
186 mutex_unlock(lock);
187}
188
189static irqreturn_t ds1307_irq(int irq, void *dev_id)
190{
191 struct i2c_client *client = dev_id;
192 struct ds1307 *ds1307 = i2c_get_clientdata(client);
193
194 disable_irq_nosync(irq);
195 schedule_work(&ds1307->work);
196 return IRQ_HANDLED;
197}
198
199/*----------------------------------------------------------------------*/
200
135static int ds1307_get_time(struct device *dev, struct rtc_time *t) 201static int ds1307_get_time(struct device *dev, struct rtc_time *t)
136{ 202{
137 struct ds1307 *ds1307 = dev_get_drvdata(dev); 203 struct ds1307 *ds1307 = dev_get_drvdata(dev);
138 int tmp; 204 int tmp;
139 205
140 /* read the RTC date and time registers all at once */ 206 /* read the RTC date and time registers all at once */
207 ds1307->reg_addr = 0;
141 ds1307->msg[1].flags = I2C_M_RD; 208 ds1307->msg[1].flags = I2C_M_RD;
142 ds1307->msg[1].len = 7; 209 ds1307->msg[1].len = 7;
143 210
@@ -231,9 +298,186 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
231 return 0; 298 return 0;
232} 299}
233 300
301static int ds1307_read_alarm(struct device *dev, struct rtc_wkalrm *t)
302{
303 struct i2c_client *client = to_i2c_client(dev);
304 struct ds1307 *ds1307 = i2c_get_clientdata(client);
305 int ret;
306
307 if (!test_bit(HAS_ALARM, &ds1307->flags))
308 return -EINVAL;
309
310 /* read all ALARM1, ALARM2, and status registers at once */
311 ds1307->reg_addr = DS1339_REG_ALARM1_SECS;
312 ds1307->msg[1].flags = I2C_M_RD;
313 ds1307->msg[1].len = 9;
314
315 ret = i2c_transfer(to_i2c_adapter(client->dev.parent),
316 ds1307->msg, 2);
317 if (ret != 2) {
318 dev_err(dev, "%s error %d\n", "alarm read", ret);
319 return -EIO;
320 }
321
322 dev_dbg(dev, "%s: %02x %02x %02x %02x, %02x %02x %02x, %02x %02x\n",
323 "alarm read",
324 ds1307->regs[0], ds1307->regs[1],
325 ds1307->regs[2], ds1307->regs[3],
326 ds1307->regs[4], ds1307->regs[5],
327 ds1307->regs[6], ds1307->regs[7],
328 ds1307->regs[8]);
329
330 /* report alarm time (ALARM1); assume 24 hour and day-of-month modes,
331 * and that all four fields are checked matches
332 */
333 t->time.tm_sec = bcd2bin(ds1307->regs[0] & 0x7f);
334 t->time.tm_min = bcd2bin(ds1307->regs[1] & 0x7f);
335 t->time.tm_hour = bcd2bin(ds1307->regs[2] & 0x3f);
336 t->time.tm_mday = bcd2bin(ds1307->regs[3] & 0x3f);
337 t->time.tm_mon = -1;
338 t->time.tm_year = -1;
339 t->time.tm_wday = -1;
340 t->time.tm_yday = -1;
341 t->time.tm_isdst = -1;
342
343 /* ... and status */
344 t->enabled = !!(ds1307->regs[7] & DS1337_BIT_A1IE);
345 t->pending = !!(ds1307->regs[8] & DS1337_BIT_A1I);
346
347 dev_dbg(dev, "%s secs=%d, mins=%d, "
348 "hours=%d, mday=%d, enabled=%d, pending=%d\n",
349 "alarm read", t->time.tm_sec, t->time.tm_min,
350 t->time.tm_hour, t->time.tm_mday,
351 t->enabled, t->pending);
352
353 return 0;
354}
355
356static int ds1307_set_alarm(struct device *dev, struct rtc_wkalrm *t)
357{
358 struct i2c_client *client = to_i2c_client(dev);
359 struct ds1307 *ds1307 = i2c_get_clientdata(client);
360 unsigned char *buf = ds1307->regs;
361 u8 control, status;
362 int ret;
363
364 if (!test_bit(HAS_ALARM, &ds1307->flags))
365 return -EINVAL;
366
367 dev_dbg(dev, "%s secs=%d, mins=%d, "
368 "hours=%d, mday=%d, enabled=%d, pending=%d\n",
369 "alarm set", t->time.tm_sec, t->time.tm_min,
370 t->time.tm_hour, t->time.tm_mday,
371 t->enabled, t->pending);
372
373 /* read current status of both alarms and the chip */
374 ds1307->reg_addr = DS1339_REG_ALARM1_SECS;
375 ds1307->msg[1].flags = I2C_M_RD;
376 ds1307->msg[1].len = 9;
377
378 ret = i2c_transfer(to_i2c_adapter(client->dev.parent),
379 ds1307->msg, 2);
380 if (ret != 2) {
381 dev_err(dev, "%s error %d\n", "alarm write", ret);
382 return -EIO;
383 }
384 control = ds1307->regs[7];
385 status = ds1307->regs[8];
386
387 dev_dbg(dev, "%s: %02x %02x %02x %02x, %02x %02x %02x, %02x %02x\n",
388 "alarm set (old status)",
389 ds1307->regs[0], ds1307->regs[1],
390 ds1307->regs[2], ds1307->regs[3],
391 ds1307->regs[4], ds1307->regs[5],
392 ds1307->regs[6], control, status);
393
394 /* set ALARM1, using 24 hour and day-of-month modes */
395 *buf++ = DS1339_REG_ALARM1_SECS; /* first register addr */
396 buf[0] = bin2bcd(t->time.tm_sec);
397 buf[1] = bin2bcd(t->time.tm_min);
398 buf[2] = bin2bcd(t->time.tm_hour);
399 buf[3] = bin2bcd(t->time.tm_mday);
400
401 /* set ALARM2 to non-garbage */
402 buf[4] = 0;
403 buf[5] = 0;
404 buf[6] = 0;
405
406 /* optionally enable ALARM1 */
407 buf[7] = control & ~(DS1337_BIT_A1IE | DS1337_BIT_A2IE);
408 if (t->enabled) {
409 dev_dbg(dev, "alarm IRQ armed\n");
410 buf[7] |= DS1337_BIT_A1IE; /* only ALARM1 is used */
411 }
412 buf[8] = status & ~(DS1337_BIT_A1I | DS1337_BIT_A2I);
413
414 ds1307->msg[1].flags = 0;
415 ds1307->msg[1].len = 10;
416
417 ret = i2c_transfer(to_i2c_adapter(client->dev.parent),
418 &ds1307->msg[1], 1);
419 if (ret != 1) {
420 dev_err(dev, "can't set alarm time\n");
421 return -EIO;
422 }
423
424 return 0;
425}
426
427static int ds1307_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
428{
429 struct i2c_client *client = to_i2c_client(dev);
430 struct ds1307 *ds1307 = i2c_get_clientdata(client);
431 int ret;
432
433 switch (cmd) {
434 case RTC_AIE_OFF:
435 if (!test_bit(HAS_ALARM, &ds1307->flags))
436 return -ENOTTY;
437
438 ret = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL);
439 if (ret < 0)
440 return ret;
441
442 ret &= ~DS1337_BIT_A1IE;
443
444 ret = i2c_smbus_write_byte_data(client,
445 DS1337_REG_CONTROL, ret);
446 if (ret < 0)
447 return ret;
448
449 break;
450
451 case RTC_AIE_ON:
452 if (!test_bit(HAS_ALARM, &ds1307->flags))
453 return -ENOTTY;
454
455 ret = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL);
456 if (ret < 0)
457 return ret;
458
459 ret |= DS1337_BIT_A1IE;
460
461 ret = i2c_smbus_write_byte_data(client,
462 DS1337_REG_CONTROL, ret);
463 if (ret < 0)
464 return ret;
465
466 break;
467
468 default:
469 return -ENOIOCTLCMD;
470 }
471
472 return 0;
473}
474
234static const struct rtc_class_ops ds13xx_rtc_ops = { 475static const struct rtc_class_ops ds13xx_rtc_ops = {
235 .read_time = ds1307_get_time, 476 .read_time = ds1307_get_time,
236 .set_time = ds1307_set_time, 477 .set_time = ds1307_set_time,
478 .read_alarm = ds1307_read_alarm,
479 .set_alarm = ds1307_set_alarm,
480 .ioctl = ds1307_ioctl,
237}; 481};
238 482
239/*----------------------------------------------------------------------*/ 483/*----------------------------------------------------------------------*/
@@ -327,6 +571,7 @@ static int __devinit ds1307_probe(struct i2c_client *client,
327 int tmp; 571 int tmp;
328 const struct chip_desc *chip = &chips[id->driver_data]; 572 const struct chip_desc *chip = &chips[id->driver_data];
329 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 573 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
574 int want_irq = false;
330 575
331 if (!i2c_check_functionality(adapter, 576 if (!i2c_check_functionality(adapter,
332 I2C_FUNC_I2C | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) 577 I2C_FUNC_I2C | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
@@ -353,6 +598,12 @@ static int __devinit ds1307_probe(struct i2c_client *client,
353 switch (ds1307->type) { 598 switch (ds1307->type) {
354 case ds_1337: 599 case ds_1337:
355 case ds_1339: 600 case ds_1339:
601 /* has IRQ? */
602 if (ds1307->client->irq > 0 && chip->alarm) {
603 INIT_WORK(&ds1307->work, ds1307_work);
604 want_irq = true;
605 }
606
356 ds1307->reg_addr = DS1337_REG_CONTROL; 607 ds1307->reg_addr = DS1337_REG_CONTROL;
357 ds1307->msg[1].len = 2; 608 ds1307->msg[1].len = 2;
358 609
@@ -369,8 +620,20 @@ static int __devinit ds1307_probe(struct i2c_client *client,
369 620
370 /* oscillator off? turn it on, so clock can tick. */ 621 /* oscillator off? turn it on, so clock can tick. */
371 if (ds1307->regs[0] & DS1337_BIT_nEOSC) 622 if (ds1307->regs[0] & DS1337_BIT_nEOSC)
372 i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL, 623 ds1307->regs[0] &= ~DS1337_BIT_nEOSC;
373 ds1307->regs[0] & ~DS1337_BIT_nEOSC); 624
625 /* Using IRQ? Disable the square wave and both alarms.
626 * For ds1339, be sure alarms can trigger when we're
627 * running on Vbackup (BBSQI); we assume ds1337 will
628 * ignore that bit
629 */
630 if (want_irq) {
631 ds1307->regs[0] |= DS1337_BIT_INTCN | DS1339_BIT_BBSQI;
632 ds1307->regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE);
633 }
634
635 i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL,
636 ds1307->regs[0]);
374 637
375 /* oscillator fault? clear flag, and warn */ 638 /* oscillator fault? clear flag, and warn */
376 if (ds1307->regs[1] & DS1337_BIT_OSF) { 639 if (ds1307->regs[1] & DS1337_BIT_OSF) {
@@ -495,10 +758,22 @@ read_rtc:
495 goto exit_free; 758 goto exit_free;
496 } 759 }
497 760
761 if (want_irq) {
762 err = request_irq(client->irq, ds1307_irq, 0,
763 ds1307->rtc->name, client);
764 if (err) {
765 dev_err(&client->dev,
766 "unable to request IRQ!\n");
767 goto exit_irq;
768 }
769 set_bit(HAS_ALARM, &ds1307->flags);
770 dev_dbg(&client->dev, "got IRQ %d\n", client->irq);
771 }
772
498 if (chip->nvram56) { 773 if (chip->nvram56) {
499 err = sysfs_create_bin_file(&client->dev.kobj, &nvram); 774 err = sysfs_create_bin_file(&client->dev.kobj, &nvram);
500 if (err == 0) { 775 if (err == 0) {
501 ds1307->has_nvram = true; 776 set_bit(HAS_NVRAM, &ds1307->flags);
502 dev_info(&client->dev, "56 bytes nvram\n"); 777 dev_info(&client->dev, "56 bytes nvram\n");
503 } 778 }
504 } 779 }
@@ -512,7 +787,9 @@ exit_bad:
512 ds1307->regs[2], ds1307->regs[3], 787 ds1307->regs[2], ds1307->regs[3],
513 ds1307->regs[4], ds1307->regs[5], 788 ds1307->regs[4], ds1307->regs[5],
514 ds1307->regs[6]); 789 ds1307->regs[6]);
515 790exit_irq:
791 if (ds1307->rtc)
792 rtc_device_unregister(ds1307->rtc);
516exit_free: 793exit_free:
517 kfree(ds1307); 794 kfree(ds1307);
518 return err; 795 return err;
@@ -520,9 +797,14 @@ exit_free:
520 797
521static int __devexit ds1307_remove(struct i2c_client *client) 798static int __devexit ds1307_remove(struct i2c_client *client)
522{ 799{
523 struct ds1307 *ds1307 = i2c_get_clientdata(client); 800 struct ds1307 *ds1307 = i2c_get_clientdata(client);
801
802 if (test_and_clear_bit(HAS_ALARM, &ds1307->flags)) {
803 free_irq(client->irq, client);
804 cancel_work_sync(&ds1307->work);
805 }
524 806
525 if (ds1307->has_nvram) 807 if (test_and_clear_bit(HAS_NVRAM, &ds1307->flags))
526 sysfs_remove_bin_file(&client->dev.kobj, &nvram); 808 sysfs_remove_bin_file(&client->dev.kobj, &nvram);
527 809
528 rtc_device_unregister(ds1307->rtc); 810 rtc_device_unregister(ds1307->rtc);
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c
index a150418fba76..a5b0fc09f0c6 100644
--- a/drivers/rtc/rtc-ds1374.c
+++ b/drivers/rtc/rtc-ds1374.c
@@ -429,12 +429,33 @@ static int __devexit ds1374_remove(struct i2c_client *client)
429 return 0; 429 return 0;
430} 430}
431 431
432#ifdef CONFIG_PM
433static int ds1374_suspend(struct i2c_client *client, pm_message_t state)
434{
435 if (client->irq >= 0 && device_may_wakeup(&client->dev))
436 enable_irq_wake(client->irq);
437 return 0;
438}
439
440static int ds1374_resume(struct i2c_client *client)
441{
442 if (client->irq >= 0 && device_may_wakeup(&client->dev))
443 disable_irq_wake(client->irq);
444 return 0;
445}
446#else
447#define ds1374_suspend NULL
448#define ds1374_resume NULL
449#endif
450
432static struct i2c_driver ds1374_driver = { 451static struct i2c_driver ds1374_driver = {
433 .driver = { 452 .driver = {
434 .name = "rtc-ds1374", 453 .name = "rtc-ds1374",
435 .owner = THIS_MODULE, 454 .owner = THIS_MODULE,
436 }, 455 },
437 .probe = ds1374_probe, 456 .probe = ds1374_probe,
457 .suspend = ds1374_suspend,
458 .resume = ds1374_resume,
438 .remove = __devexit_p(ds1374_remove), 459 .remove = __devexit_p(ds1374_remove),
439 .id_table = ds1374_id, 460 .id_table = ds1374_id,
440}; 461};
diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c
index 0f0d27d1c4ca..86981d34fbb6 100644
--- a/drivers/rtc/rtc-ds1511.c
+++ b/drivers/rtc/rtc-ds1511.c
@@ -379,18 +379,6 @@ ds1511_interrupt(int irq, void *dev_id)
379 return IRQ_HANDLED; 379 return IRQ_HANDLED;
380} 380}
381 381
382 static void
383ds1511_rtc_release(struct device *dev)
384{
385 struct platform_device *pdev = to_platform_device(dev);
386 struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
387
388 if (pdata->irq >= 0) {
389 pdata->irqen = 0;
390 ds1511_rtc_update_alarm(pdata);
391 }
392}
393
394 static int 382 static int
395ds1511_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) 383ds1511_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
396{ 384{
@@ -428,7 +416,6 @@ static const struct rtc_class_ops ds1511_rtc_ops = {
428 .set_time = ds1511_rtc_set_time, 416 .set_time = ds1511_rtc_set_time,
429 .read_alarm = ds1511_rtc_read_alarm, 417 .read_alarm = ds1511_rtc_read_alarm,
430 .set_alarm = ds1511_rtc_set_alarm, 418 .set_alarm = ds1511_rtc_set_alarm,
431 .release = ds1511_rtc_release,
432 .ioctl = ds1511_rtc_ioctl, 419 .ioctl = ds1511_rtc_ioctl,
433}; 420};
434 421
diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c
index a19f11415540..4ef59285b489 100644
--- a/drivers/rtc/rtc-ds1553.c
+++ b/drivers/rtc/rtc-ds1553.c
@@ -207,17 +207,6 @@ static irqreturn_t ds1553_rtc_interrupt(int irq, void *dev_id)
207 return IRQ_HANDLED; 207 return IRQ_HANDLED;
208} 208}
209 209
210static void ds1553_rtc_release(struct device *dev)
211{
212 struct platform_device *pdev = to_platform_device(dev);
213 struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
214
215 if (pdata->irq >= 0) {
216 pdata->irqen = 0;
217 ds1553_rtc_update_alarm(pdata);
218 }
219}
220
221static int ds1553_rtc_ioctl(struct device *dev, unsigned int cmd, 210static int ds1553_rtc_ioctl(struct device *dev, unsigned int cmd,
222 unsigned long arg) 211 unsigned long arg)
223{ 212{
@@ -254,7 +243,6 @@ static const struct rtc_class_ops ds1553_rtc_ops = {
254 .set_time = ds1553_rtc_set_time, 243 .set_time = ds1553_rtc_set_time,
255 .read_alarm = ds1553_rtc_read_alarm, 244 .read_alarm = ds1553_rtc_read_alarm,
256 .set_alarm = ds1553_rtc_set_alarm, 245 .set_alarm = ds1553_rtc_set_alarm,
257 .release = ds1553_rtc_release,
258 .ioctl = ds1553_rtc_ioctl, 246 .ioctl = ds1553_rtc_ioctl,
259}; 247};
260 248
diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c
index 6fa4556f5f5c..341d7a5b45a2 100644
--- a/drivers/rtc/rtc-ds1672.c
+++ b/drivers/rtc/rtc-ds1672.c
@@ -9,17 +9,10 @@
9 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
10 */ 10 */
11 11
12#include <linux/module.h>
13#include <linux/i2c.h> 12#include <linux/i2c.h>
14#include <linux/rtc.h> 13#include <linux/rtc.h>
15 14
16#define DRV_VERSION "0.3" 15#define DRV_VERSION "0.4"
17
18/* Addresses to scan: none. This chip cannot be detected. */
19static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
20
21/* Insmod parameters */
22I2C_CLIENT_INSMOD;
23 16
24/* Registers */ 17/* Registers */
25 18
@@ -29,8 +22,7 @@ I2C_CLIENT_INSMOD;
29 22
30#define DS1672_REG_CONTROL_EOSC 0x80 23#define DS1672_REG_CONTROL_EOSC 0x80
31 24
32/* Prototypes */ 25static struct i2c_driver ds1672_driver;
33static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind);
34 26
35/* 27/*
36 * In the routines that deal directly with the ds1672 hardware, we use 28 * In the routines that deal directly with the ds1672 hardware, we use
@@ -44,8 +36,8 @@ static int ds1672_get_datetime(struct i2c_client *client, struct rtc_time *tm)
44 unsigned char buf[4]; 36 unsigned char buf[4];
45 37
46 struct i2c_msg msgs[] = { 38 struct i2c_msg msgs[] = {
47 { client->addr, 0, 1, &addr }, /* setup read ptr */ 39 {client->addr, 0, 1, &addr}, /* setup read ptr */
48 { client->addr, I2C_M_RD, 4, buf }, /* read date */ 40 {client->addr, I2C_M_RD, 4, buf}, /* read date */
49 }; 41 };
50 42
51 /* read date registers */ 43 /* read date registers */
@@ -80,7 +72,7 @@ static int ds1672_set_mmss(struct i2c_client *client, unsigned long secs)
80 buf[2] = (secs & 0x0000FF00) >> 8; 72 buf[2] = (secs & 0x0000FF00) >> 8;
81 buf[3] = (secs & 0x00FF0000) >> 16; 73 buf[3] = (secs & 0x00FF0000) >> 16;
82 buf[4] = (secs & 0xFF000000) >> 24; 74 buf[4] = (secs & 0xFF000000) >> 24;
83 buf[5] = 0; /* set control reg to enable counting */ 75 buf[5] = 0; /* set control reg to enable counting */
84 76
85 xfer = i2c_master_send(client, buf, 6); 77 xfer = i2c_master_send(client, buf, 6);
86 if (xfer != 6) { 78 if (xfer != 6) {
@@ -127,8 +119,8 @@ static int ds1672_get_control(struct i2c_client *client, u8 *status)
127 unsigned char addr = DS1672_REG_CONTROL; 119 unsigned char addr = DS1672_REG_CONTROL;
128 120
129 struct i2c_msg msgs[] = { 121 struct i2c_msg msgs[] = {
130 { client->addr, 0, 1, &addr }, /* setup read ptr */ 122 {client->addr, 0, 1, &addr}, /* setup read ptr */
131 { client->addr, I2C_M_RD, 1, status }, /* read control */ 123 {client->addr, I2C_M_RD, 1, status}, /* read control */
132 }; 124 };
133 125
134 /* read control register */ 126 /* read control register */
@@ -141,7 +133,8 @@ static int ds1672_get_control(struct i2c_client *client, u8 *status)
141} 133}
142 134
143/* following are the sysfs callback functions */ 135/* following are the sysfs callback functions */
144static ssize_t show_control(struct device *dev, struct device_attribute *attr, char *buf) 136static ssize_t show_control(struct device *dev, struct device_attribute *attr,
137 char *buf)
145{ 138{
146 struct i2c_client *client = to_i2c_client(dev); 139 struct i2c_client *client = to_i2c_client(dev);
147 u8 control; 140 u8 control;
@@ -152,85 +145,46 @@ static ssize_t show_control(struct device *dev, struct device_attribute *attr, c
152 return err; 145 return err;
153 146
154 return sprintf(buf, "%s\n", (control & DS1672_REG_CONTROL_EOSC) 147 return sprintf(buf, "%s\n", (control & DS1672_REG_CONTROL_EOSC)
155 ? "disabled" : "enabled"); 148 ? "disabled" : "enabled");
156} 149}
150
157static DEVICE_ATTR(control, S_IRUGO, show_control, NULL); 151static DEVICE_ATTR(control, S_IRUGO, show_control, NULL);
158 152
159static const struct rtc_class_ops ds1672_rtc_ops = { 153static const struct rtc_class_ops ds1672_rtc_ops = {
160 .read_time = ds1672_rtc_read_time, 154 .read_time = ds1672_rtc_read_time,
161 .set_time = ds1672_rtc_set_time, 155 .set_time = ds1672_rtc_set_time,
162 .set_mmss = ds1672_rtc_set_mmss, 156 .set_mmss = ds1672_rtc_set_mmss,
163}; 157};
164 158
165static int ds1672_attach(struct i2c_adapter *adapter) 159static int ds1672_remove(struct i2c_client *client)
166{ 160{
167 return i2c_probe(adapter, &addr_data, ds1672_probe);
168}
169
170static int ds1672_detach(struct i2c_client *client)
171{
172 int err;
173 struct rtc_device *rtc = i2c_get_clientdata(client); 161 struct rtc_device *rtc = i2c_get_clientdata(client);
174 162
175 if (rtc) 163 if (rtc)
176 rtc_device_unregister(rtc); 164 rtc_device_unregister(rtc);
177 165
178 if ((err = i2c_detach_client(client)))
179 return err;
180
181 kfree(client);
182
183 return 0; 166 return 0;
184} 167}
185 168
186static struct i2c_driver ds1672_driver = { 169static int ds1672_probe(struct i2c_client *client,
187 .driver = { 170 const struct i2c_device_id *id)
188 .name = "ds1672",
189 },
190 .id = I2C_DRIVERID_DS1672,
191 .attach_adapter = &ds1672_attach,
192 .detach_client = &ds1672_detach,
193};
194
195static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind)
196{ 171{
197 int err = 0; 172 int err = 0;
198 u8 control; 173 u8 control;
199 struct i2c_client *client;
200 struct rtc_device *rtc; 174 struct rtc_device *rtc;
201 175
202 dev_dbg(&adapter->dev, "%s\n", __func__); 176 dev_dbg(&client->dev, "%s\n", __func__);
203 177
204 if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { 178 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
205 err = -ENODEV; 179 return -ENODEV;
206 goto exit;
207 }
208
209 if (!(client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL))) {
210 err = -ENOMEM;
211 goto exit;
212 }
213
214 /* I2C client */
215 client->addr = address;
216 client->driver = &ds1672_driver;
217 client->adapter = adapter;
218
219 strlcpy(client->name, ds1672_driver.driver.name, I2C_NAME_SIZE);
220
221 /* Inform the i2c layer */
222 if ((err = i2c_attach_client(client)))
223 goto exit_kfree;
224 180
225 dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); 181 dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
226 182
227 rtc = rtc_device_register(ds1672_driver.driver.name, &client->dev, 183 rtc = rtc_device_register(ds1672_driver.driver.name, &client->dev,
228 &ds1672_rtc_ops, THIS_MODULE); 184 &ds1672_rtc_ops, THIS_MODULE);
229 185
230 if (IS_ERR(rtc)) { 186 if (IS_ERR(rtc))
231 err = PTR_ERR(rtc); 187 return PTR_ERR(rtc);
232 goto exit_detach;
233 }
234 188
235 i2c_set_clientdata(client, rtc); 189 i2c_set_clientdata(client, rtc);
236 190
@@ -241,7 +195,7 @@ static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind)
241 195
242 if (control & DS1672_REG_CONTROL_EOSC) 196 if (control & DS1672_REG_CONTROL_EOSC)
243 dev_warn(&client->dev, "Oscillator not enabled. " 197 dev_warn(&client->dev, "Oscillator not enabled. "
244 "Set time to enable.\n"); 198 "Set time to enable.\n");
245 199
246 /* Register sysfs hooks */ 200 /* Register sysfs hooks */
247 err = device_create_file(&client->dev, &dev_attr_control); 201 err = device_create_file(&client->dev, &dev_attr_control);
@@ -250,19 +204,19 @@ static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind)
250 204
251 return 0; 205 return 0;
252 206
253exit_devreg: 207 exit_devreg:
254 rtc_device_unregister(rtc); 208 rtc_device_unregister(rtc);
255
256exit_detach:
257 i2c_detach_client(client);
258
259exit_kfree:
260 kfree(client);
261
262exit:
263 return err; 209 return err;
264} 210}
265 211
212static struct i2c_driver ds1672_driver = {
213 .driver = {
214 .name = "rtc-ds1672",
215 },
216 .probe = &ds1672_probe,
217 .remove = &ds1672_remove,
218};
219
266static int __init ds1672_init(void) 220static int __init ds1672_init(void)
267{ 221{
268 return i2c_add_driver(&ds1672_driver); 222 return i2c_add_driver(&ds1672_driver);
diff --git a/drivers/rtc/rtc-ds3234.c b/drivers/rtc/rtc-ds3234.c
new file mode 100644
index 000000000000..37d131d03f33
--- /dev/null
+++ b/drivers/rtc/rtc-ds3234.c
@@ -0,0 +1,290 @@
1/* drivers/rtc/rtc-ds3234.c
2 *
3 * Driver for Dallas Semiconductor (DS3234) SPI RTC with Integrated Crystal
4 * and SRAM.
5 *
6 * Copyright (C) 2008 MIMOMax Wireless Ltd.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * Changelog:
13 *
14 * 07-May-2008: Dennis Aberilla <denzzzhome@yahoo.com>
15 * - Created based on the max6902 code. Only implements the
16 * date/time keeping functions; no SRAM yet.
17 */
18
19#include <linux/device.h>
20#include <linux/platform_device.h>
21#include <linux/rtc.h>
22#include <linux/spi/spi.h>
23#include <linux/bcd.h>
24
25#define DS3234_REG_SECONDS 0x00
26#define DS3234_REG_MINUTES 0x01
27#define DS3234_REG_HOURS 0x02
28#define DS3234_REG_DAY 0x03
29#define DS3234_REG_DATE 0x04
30#define DS3234_REG_MONTH 0x05
31#define DS3234_REG_YEAR 0x06
32#define DS3234_REG_CENTURY (1 << 7) /* Bit 7 of the Month register */
33
34#define DS3234_REG_CONTROL 0x0E
35#define DS3234_REG_CONT_STAT 0x0F
36
37#undef DS3234_DEBUG
38
39struct ds3234 {
40 struct rtc_device *rtc;
41 u8 buf[8]; /* Burst read: addr + 7 regs */
42 u8 tx_buf[2];
43 u8 rx_buf[2];
44};
45
46static void ds3234_set_reg(struct device *dev, unsigned char address,
47 unsigned char data)
48{
49 struct spi_device *spi = to_spi_device(dev);
50 unsigned char buf[2];
51
52 /* MSB must be '1' to indicate write */
53 buf[0] = address | 0x80;
54 buf[1] = data;
55
56 spi_write(spi, buf, 2);
57}
58
59static int ds3234_get_reg(struct device *dev, unsigned char address,
60 unsigned char *data)
61{
62 struct spi_device *spi = to_spi_device(dev);
63 struct ds3234 *chip = dev_get_drvdata(dev);
64 struct spi_message message;
65 struct spi_transfer xfer;
66 int status;
67
68 if (!data)
69 return -EINVAL;
70
71 /* Build our spi message */
72 spi_message_init(&message);
73 memset(&xfer, 0, sizeof(xfer));
74
75 /* Address + dummy tx byte */
76 xfer.len = 2;
77 xfer.tx_buf = chip->tx_buf;
78 xfer.rx_buf = chip->rx_buf;
79
80 chip->tx_buf[0] = address;
81 chip->tx_buf[1] = 0xff;
82
83 spi_message_add_tail(&xfer, &message);
84
85 /* do the i/o */
86 status = spi_sync(spi, &message);
87 if (status == 0)
88 status = message.status;
89 else
90 return status;
91
92 *data = chip->rx_buf[1];
93
94 return status;
95}
96
97static int ds3234_get_datetime(struct device *dev, struct rtc_time *dt)
98{
99 struct spi_device *spi = to_spi_device(dev);
100 struct ds3234 *chip = dev_get_drvdata(dev);
101 struct spi_message message;
102 struct spi_transfer xfer;
103 int status;
104
105 /* build the message */
106 spi_message_init(&message);
107 memset(&xfer, 0, sizeof(xfer));
108 xfer.len = 1 + 7; /* Addr + 7 registers */
109 xfer.tx_buf = chip->buf;
110 xfer.rx_buf = chip->buf;
111 chip->buf[0] = 0x00; /* Start address */
112 spi_message_add_tail(&xfer, &message);
113
114 /* do the i/o */
115 status = spi_sync(spi, &message);
116 if (status == 0)
117 status = message.status;
118 else
119 return status;
120
121 /* Seconds, Minutes, Hours, Day, Date, Month, Year */
122 dt->tm_sec = bcd2bin(chip->buf[1]);
123 dt->tm_min = bcd2bin(chip->buf[2]);
124 dt->tm_hour = bcd2bin(chip->buf[3] & 0x3f);
125 dt->tm_wday = bcd2bin(chip->buf[4]) - 1; /* 0 = Sun */
126 dt->tm_mday = bcd2bin(chip->buf[5]);
127 dt->tm_mon = bcd2bin(chip->buf[6] & 0x1f) - 1; /* 0 = Jan */
128 dt->tm_year = bcd2bin(chip->buf[7] & 0xff) + 100; /* Assume 20YY */
129
130#ifdef DS3234_DEBUG
131 dev_dbg(dev, "\n%s : Read RTC values\n", __func__);
132 dev_dbg(dev, "tm_hour: %i\n", dt->tm_hour);
133 dev_dbg(dev, "tm_min : %i\n", dt->tm_min);
134 dev_dbg(dev, "tm_sec : %i\n", dt->tm_sec);
135 dev_dbg(dev, "tm_wday: %i\n", dt->tm_wday);
136 dev_dbg(dev, "tm_mday: %i\n", dt->tm_mday);
137 dev_dbg(dev, "tm_mon : %i\n", dt->tm_mon);
138 dev_dbg(dev, "tm_year: %i\n", dt->tm_year);
139#endif
140
141 return 0;
142}
143
144static int ds3234_set_datetime(struct device *dev, struct rtc_time *dt)
145{
146#ifdef DS3234_DEBUG
147 dev_dbg(dev, "\n%s : Setting RTC values\n", __func__);
148 dev_dbg(dev, "tm_sec : %i\n", dt->tm_sec);
149 dev_dbg(dev, "tm_min : %i\n", dt->tm_min);
150 dev_dbg(dev, "tm_hour: %i\n", dt->tm_hour);
151 dev_dbg(dev, "tm_wday: %i\n", dt->tm_wday);
152 dev_dbg(dev, "tm_mday: %i\n", dt->tm_mday);
153 dev_dbg(dev, "tm_mon : %i\n", dt->tm_mon);
154 dev_dbg(dev, "tm_year: %i\n", dt->tm_year);
155#endif
156
157 ds3234_set_reg(dev, DS3234_REG_SECONDS, bin2bcd(dt->tm_sec));
158 ds3234_set_reg(dev, DS3234_REG_MINUTES, bin2bcd(dt->tm_min));
159 ds3234_set_reg(dev, DS3234_REG_HOURS, bin2bcd(dt->tm_hour) & 0x3f);
160
161 /* 0 = Sun */
162 ds3234_set_reg(dev, DS3234_REG_DAY, bin2bcd(dt->tm_wday + 1));
163 ds3234_set_reg(dev, DS3234_REG_DATE, bin2bcd(dt->tm_mday));
164
165 /* 0 = Jan */
166 ds3234_set_reg(dev, DS3234_REG_MONTH, bin2bcd(dt->tm_mon + 1));
167
168 /* Assume 20YY although we just want to make sure not to go negative. */
169 if (dt->tm_year > 100)
170 dt->tm_year -= 100;
171
172 ds3234_set_reg(dev, DS3234_REG_YEAR, bin2bcd(dt->tm_year));
173
174 return 0;
175}
176
177static int ds3234_read_time(struct device *dev, struct rtc_time *tm)
178{
179 return ds3234_get_datetime(dev, tm);
180}
181
182static int ds3234_set_time(struct device *dev, struct rtc_time *tm)
183{
184 return ds3234_set_datetime(dev, tm);
185}
186
187static const struct rtc_class_ops ds3234_rtc_ops = {
188 .read_time = ds3234_read_time,
189 .set_time = ds3234_set_time,
190};
191
192static int ds3234_probe(struct spi_device *spi)
193{
194 struct rtc_device *rtc;
195 unsigned char tmp;
196 struct ds3234 *chip;
197 int res;
198
199 rtc = rtc_device_register("ds3234",
200 &spi->dev, &ds3234_rtc_ops, THIS_MODULE);
201 if (IS_ERR(rtc))
202 return PTR_ERR(rtc);
203
204 spi->mode = SPI_MODE_3;
205 spi->bits_per_word = 8;
206 spi_setup(spi);
207
208 chip = kzalloc(sizeof(struct ds3234), GFP_KERNEL);
209 if (!chip) {
210 rtc_device_unregister(rtc);
211 return -ENOMEM;
212 }
213 chip->rtc = rtc;
214 dev_set_drvdata(&spi->dev, chip);
215
216 res = ds3234_get_reg(&spi->dev, DS3234_REG_SECONDS, &tmp);
217 if (res) {
218 rtc_device_unregister(rtc);
219 return res;
220 }
221
222 /* Control settings
223 *
224 * CONTROL_REG
225 * BIT 7 6 5 4 3 2 1 0
226 * EOSC BBSQW CONV RS2 RS1 INTCN A2IE A1IE
227 *
228 * 0 0 0 1 1 1 0 0
229 *
230 * CONTROL_STAT_REG
231 * BIT 7 6 5 4 3 2 1 0
232 * OSF BB32kHz CRATE1 CRATE0 EN32kHz BSY A2F A1F
233 *
234 * 1 0 0 0 1 0 0 0
235 */
236 ds3234_get_reg(&spi->dev, DS3234_REG_CONTROL, &tmp);
237 ds3234_set_reg(&spi->dev, DS3234_REG_CONTROL, tmp & 0x1c);
238
239 ds3234_get_reg(&spi->dev, DS3234_REG_CONT_STAT, &tmp);
240 ds3234_set_reg(&spi->dev, DS3234_REG_CONT_STAT, tmp & 0x88);
241
242 /* Print our settings */
243 ds3234_get_reg(&spi->dev, DS3234_REG_CONTROL, &tmp);
244 dev_info(&spi->dev, "Control Reg: 0x%02x\n", tmp);
245
246 ds3234_get_reg(&spi->dev, DS3234_REG_CONT_STAT, &tmp);
247 dev_info(&spi->dev, "Ctrl/Stat Reg: 0x%02x\n", tmp);
248
249 return 0;
250}
251
252static int __exit ds3234_remove(struct spi_device *spi)
253{
254 struct ds3234 *chip = platform_get_drvdata(spi);
255 struct rtc_device *rtc = chip->rtc;
256
257 if (rtc)
258 rtc_device_unregister(rtc);
259
260 kfree(chip);
261
262 return 0;
263}
264
265static struct spi_driver ds3234_driver = {
266 .driver = {
267 .name = "ds3234",
268 .bus = &spi_bus_type,
269 .owner = THIS_MODULE,
270 },
271 .probe = ds3234_probe,
272 .remove = __devexit_p(ds3234_remove),
273};
274
275static __init int ds3234_init(void)
276{
277 printk(KERN_INFO "DS3234 SPI RTC Driver\n");
278 return spi_register_driver(&ds3234_driver);
279}
280module_init(ds3234_init);
281
282static __exit void ds3234_exit(void)
283{
284 spi_unregister_driver(&ds3234_driver);
285}
286module_exit(ds3234_exit);
287
288MODULE_DESCRIPTION("DS3234 SPI RTC driver");
289MODULE_AUTHOR("Dennis Aberilla <denzzzhome@yahoo.com>");
290MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
index 24bc1689fc74..470fb2d29545 100644
--- a/drivers/rtc/rtc-m41t80.c
+++ b/drivers/rtc/rtc-m41t80.c
@@ -56,21 +56,27 @@
56#define M41T80_ALHOUR_HT (1 << 6) /* HT: Halt Update Bit */ 56#define M41T80_ALHOUR_HT (1 << 6) /* HT: Halt Update Bit */
57#define M41T80_FLAGS_AF (1 << 6) /* AF: Alarm Flag Bit */ 57#define M41T80_FLAGS_AF (1 << 6) /* AF: Alarm Flag Bit */
58#define M41T80_FLAGS_BATT_LOW (1 << 4) /* BL: Battery Low Bit */ 58#define M41T80_FLAGS_BATT_LOW (1 << 4) /* BL: Battery Low Bit */
59#define M41T80_WATCHDOG_RB2 (1 << 7) /* RB: Watchdog resolution */
60#define M41T80_WATCHDOG_RB1 (1 << 1) /* RB: Watchdog resolution */
61#define M41T80_WATCHDOG_RB0 (1 << 0) /* RB: Watchdog resolution */
59 62
60#define M41T80_FEATURE_HT (1 << 0) 63#define M41T80_FEATURE_HT (1 << 0) /* Halt feature */
61#define M41T80_FEATURE_BL (1 << 1) 64#define M41T80_FEATURE_BL (1 << 1) /* Battery low indicator */
65#define M41T80_FEATURE_SQ (1 << 2) /* Squarewave feature */
66#define M41T80_FEATURE_WD (1 << 3) /* Extra watchdog resolution */
62 67
63#define DRV_VERSION "0.05" 68#define DRV_VERSION "0.05"
64 69
65static const struct i2c_device_id m41t80_id[] = { 70static const struct i2c_device_id m41t80_id[] = {
66 { "m41t80", 0 }, 71 { "m41t65", M41T80_FEATURE_HT | M41T80_FEATURE_WD },
67 { "m41t81", M41T80_FEATURE_HT }, 72 { "m41t80", M41T80_FEATURE_SQ },
68 { "m41t81s", M41T80_FEATURE_HT | M41T80_FEATURE_BL }, 73 { "m41t81", M41T80_FEATURE_HT | M41T80_FEATURE_SQ},
69 { "m41t82", M41T80_FEATURE_HT | M41T80_FEATURE_BL }, 74 { "m41t81s", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ },
70 { "m41t83", M41T80_FEATURE_HT | M41T80_FEATURE_BL }, 75 { "m41t82", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ },
71 { "m41st84", M41T80_FEATURE_HT | M41T80_FEATURE_BL }, 76 { "m41t83", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ },
72 { "m41st85", M41T80_FEATURE_HT | M41T80_FEATURE_BL }, 77 { "m41st84", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ },
73 { "m41st87", M41T80_FEATURE_HT | M41T80_FEATURE_BL }, 78 { "m41st85", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ },
79 { "m41st87", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ },
74 { } 80 { }
75}; 81};
76MODULE_DEVICE_TABLE(i2c, m41t80_id); 82MODULE_DEVICE_TABLE(i2c, m41t80_id);
@@ -386,8 +392,12 @@ static ssize_t m41t80_sysfs_show_sqwfreq(struct device *dev,
386 struct device_attribute *attr, char *buf) 392 struct device_attribute *attr, char *buf)
387{ 393{
388 struct i2c_client *client = to_i2c_client(dev); 394 struct i2c_client *client = to_i2c_client(dev);
395 struct m41t80_data *clientdata = i2c_get_clientdata(client);
389 int val; 396 int val;
390 397
398 if (!(clientdata->features & M41T80_FEATURE_SQ))
399 return -EINVAL;
400
391 val = i2c_smbus_read_byte_data(client, M41T80_REG_SQW); 401 val = i2c_smbus_read_byte_data(client, M41T80_REG_SQW);
392 if (val < 0) 402 if (val < 0)
393 return -EIO; 403 return -EIO;
@@ -408,9 +418,13 @@ static ssize_t m41t80_sysfs_set_sqwfreq(struct device *dev,
408 const char *buf, size_t count) 418 const char *buf, size_t count)
409{ 419{
410 struct i2c_client *client = to_i2c_client(dev); 420 struct i2c_client *client = to_i2c_client(dev);
421 struct m41t80_data *clientdata = i2c_get_clientdata(client);
411 int almon, sqw; 422 int almon, sqw;
412 int val = simple_strtoul(buf, NULL, 0); 423 int val = simple_strtoul(buf, NULL, 0);
413 424
425 if (!(clientdata->features & M41T80_FEATURE_SQ))
426 return -EINVAL;
427
414 if (val) { 428 if (val) {
415 if (!is_power_of_2(val)) 429 if (!is_power_of_2(val))
416 return -EINVAL; 430 return -EINVAL;
@@ -499,6 +513,8 @@ static void wdt_ping(void)
499 .buf = i2c_data, 513 .buf = i2c_data,
500 }, 514 },
501 }; 515 };
516 struct m41t80_data *clientdata = i2c_get_clientdata(save_client);
517
502 i2c_data[0] = 0x09; /* watchdog register */ 518 i2c_data[0] = 0x09; /* watchdog register */
503 519
504 if (wdt_margin > 31) 520 if (wdt_margin > 31)
@@ -509,6 +525,13 @@ static void wdt_ping(void)
509 */ 525 */
510 i2c_data[1] = wdt_margin<<2 | 0x82; 526 i2c_data[1] = wdt_margin<<2 | 0x82;
511 527
528 /*
529 * M41T65 has three bits for watchdog resolution. Don't set bit 7, as
530 * that would be an invalid resolution.
531 */
532 if (clientdata->features & M41T80_FEATURE_WD)
533 i2c_data[1] &= ~M41T80_WATCHDOG_RB2;
534
512 i2c_transfer(save_client->adapter, msgs1, 1); 535 i2c_transfer(save_client->adapter, msgs1, 1);
513} 536}
514 537
diff --git a/drivers/rtc/rtc-m48t35.c b/drivers/rtc/rtc-m48t35.c
index b9c1fe4a198e..0b2197559940 100644
--- a/drivers/rtc/rtc-m48t35.c
+++ b/drivers/rtc/rtc-m48t35.c
@@ -18,6 +18,7 @@
18#include <linux/rtc.h> 18#include <linux/rtc.h>
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/bcd.h> 20#include <linux/bcd.h>
21#include <linux/io.h>
21 22
22#define DRV_VERSION "1.0" 23#define DRV_VERSION "1.0"
23 24
diff --git a/drivers/rtc/rtc-max6900.c b/drivers/rtc/rtc-max6900.c
index ded3c0abad83..12c9cd25cad8 100644
--- a/drivers/rtc/rtc-max6900.c
+++ b/drivers/rtc/rtc-max6900.c
@@ -17,19 +17,18 @@
17#include <linux/rtc.h> 17#include <linux/rtc.h>
18#include <linux/delay.h> 18#include <linux/delay.h>
19 19
20#define DRV_NAME "max6900" 20#define DRV_VERSION "0.2"
21#define DRV_VERSION "0.1"
22 21
23/* 22/*
24 * register indices 23 * register indices
25 */ 24 */
26#define MAX6900_REG_SC 0 /* seconds 00-59 */ 25#define MAX6900_REG_SC 0 /* seconds 00-59 */
27#define MAX6900_REG_MN 1 /* minutes 00-59 */ 26#define MAX6900_REG_MN 1 /* minutes 00-59 */
28#define MAX6900_REG_HR 2 /* hours 00-23 */ 27#define MAX6900_REG_HR 2 /* hours 00-23 */
29#define MAX6900_REG_DT 3 /* day of month 00-31 */ 28#define MAX6900_REG_DT 3 /* day of month 00-31 */
30#define MAX6900_REG_MO 4 /* month 01-12 */ 29#define MAX6900_REG_MO 4 /* month 01-12 */
31#define MAX6900_REG_DW 5 /* day of week 1-7 */ 30#define MAX6900_REG_DW 5 /* day of week 1-7 */
32#define MAX6900_REG_YR 6 /* year 00-99 */ 31#define MAX6900_REG_YR 6 /* year 00-99 */
33#define MAX6900_REG_CT 7 /* control */ 32#define MAX6900_REG_CT 7 /* control */
34 /* register 8 is undocumented */ 33 /* register 8 is undocumented */
35#define MAX6900_REG_CENTURY 9 /* century */ 34#define MAX6900_REG_CENTURY 9 /* century */
@@ -39,7 +38,6 @@
39 38
40#define MAX6900_REG_CT_WP (1 << 7) /* Write Protect */ 39#define MAX6900_REG_CT_WP (1 << 7) /* Write Protect */
41 40
42
43/* 41/*
44 * register read/write commands 42 * register read/write commands
45 */ 43 */
@@ -52,16 +50,7 @@
52 50
53#define MAX6900_IDLE_TIME_AFTER_WRITE 3 /* specification says 2.5 mS */ 51#define MAX6900_IDLE_TIME_AFTER_WRITE 3 /* specification says 2.5 mS */
54 52
55#define MAX6900_I2C_ADDR 0xa0 53static struct i2c_driver max6900_driver;
56
57static const unsigned short normal_i2c[] = {
58 MAX6900_I2C_ADDR >> 1,
59 I2C_CLIENT_END
60};
61
62I2C_CLIENT_INSMOD; /* defines addr_data */
63
64static int max6900_probe(struct i2c_adapter *adapter, int addr, int kind);
65 54
66static int max6900_i2c_read_regs(struct i2c_client *client, u8 *buf) 55static int max6900_i2c_read_regs(struct i2c_client *client, u8 *buf)
67{ 56{
@@ -69,36 +58,35 @@ static int max6900_i2c_read_regs(struct i2c_client *client, u8 *buf)
69 u8 reg_century_read[1] = { MAX6900_REG_CENTURY_READ }; 58 u8 reg_century_read[1] = { MAX6900_REG_CENTURY_READ };
70 struct i2c_msg msgs[4] = { 59 struct i2c_msg msgs[4] = {
71 { 60 {
72 .addr = client->addr, 61 .addr = client->addr,
73 .flags = 0, /* write */ 62 .flags = 0, /* write */
74 .len = sizeof(reg_burst_read), 63 .len = sizeof(reg_burst_read),
75 .buf = reg_burst_read 64 .buf = reg_burst_read}
76 }, 65 ,
77 { 66 {
78 .addr = client->addr, 67 .addr = client->addr,
79 .flags = I2C_M_RD, 68 .flags = I2C_M_RD,
80 .len = MAX6900_BURST_LEN, 69 .len = MAX6900_BURST_LEN,
81 .buf = buf 70 .buf = buf}
82 }, 71 ,
83 { 72 {
84 .addr = client->addr, 73 .addr = client->addr,
85 .flags = 0, /* write */ 74 .flags = 0, /* write */
86 .len = sizeof(reg_century_read), 75 .len = sizeof(reg_century_read),
87 .buf = reg_century_read 76 .buf = reg_century_read}
88 }, 77 ,
89 { 78 {
90 .addr = client->addr, 79 .addr = client->addr,
91 .flags = I2C_M_RD, 80 .flags = I2C_M_RD,
92 .len = sizeof(buf[MAX6900_REG_CENTURY]), 81 .len = sizeof(buf[MAX6900_REG_CENTURY]),
93 .buf = &buf[MAX6900_REG_CENTURY] 82 .buf = &buf[MAX6900_REG_CENTURY]
94 } 83 }
95 }; 84 };
96 int rc; 85 int rc;
97 86
98 rc = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); 87 rc = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
99 if (rc != ARRAY_SIZE(msgs)) { 88 if (rc != ARRAY_SIZE(msgs)) {
100 dev_err(&client->dev, "%s: register read failed\n", 89 dev_err(&client->dev, "%s: register read failed\n", __func__);
101 __func__);
102 return -EIO; 90 return -EIO;
103 } 91 }
104 return 0; 92 return 0;
@@ -109,20 +97,18 @@ static int max6900_i2c_write_regs(struct i2c_client *client, u8 const *buf)
109 u8 i2c_century_buf[1 + 1] = { MAX6900_REG_CENTURY_WRITE }; 97 u8 i2c_century_buf[1 + 1] = { MAX6900_REG_CENTURY_WRITE };
110 struct i2c_msg century_msgs[1] = { 98 struct i2c_msg century_msgs[1] = {
111 { 99 {
112 .addr = client->addr, 100 .addr = client->addr,
113 .flags = 0, /* write */ 101 .flags = 0, /* write */
114 .len = sizeof(i2c_century_buf), 102 .len = sizeof(i2c_century_buf),
115 .buf = i2c_century_buf 103 .buf = i2c_century_buf}
116 }
117 }; 104 };
118 u8 i2c_burst_buf[MAX6900_BURST_LEN + 1] = { MAX6900_REG_BURST_WRITE }; 105 u8 i2c_burst_buf[MAX6900_BURST_LEN + 1] = { MAX6900_REG_BURST_WRITE };
119 struct i2c_msg burst_msgs[1] = { 106 struct i2c_msg burst_msgs[1] = {
120 { 107 {
121 .addr = client->addr, 108 .addr = client->addr,
122 .flags = 0, /* write */ 109 .flags = 0, /* write */
123 .len = sizeof(i2c_burst_buf), 110 .len = sizeof(i2c_burst_buf),
124 .buf = i2c_burst_buf 111 .buf = i2c_burst_buf}
125 }
126 }; 112 };
127 int rc; 113 int rc;
128 114
@@ -133,10 +119,12 @@ static int max6900_i2c_write_regs(struct i2c_client *client, u8 const *buf)
133 * bit as part of the burst write. 119 * bit as part of the burst write.
134 */ 120 */
135 i2c_century_buf[1] = buf[MAX6900_REG_CENTURY]; 121 i2c_century_buf[1] = buf[MAX6900_REG_CENTURY];
122
136 rc = i2c_transfer(client->adapter, century_msgs, 123 rc = i2c_transfer(client->adapter, century_msgs,
137 ARRAY_SIZE(century_msgs)); 124 ARRAY_SIZE(century_msgs));
138 if (rc != ARRAY_SIZE(century_msgs)) 125 if (rc != ARRAY_SIZE(century_msgs))
139 goto write_failed; 126 goto write_failed;
127
140 msleep(MAX6900_IDLE_TIME_AFTER_WRITE); 128 msleep(MAX6900_IDLE_TIME_AFTER_WRITE);
141 129
142 memcpy(&i2c_burst_buf[1], buf, MAX6900_BURST_LEN); 130 memcpy(&i2c_burst_buf[1], buf, MAX6900_BURST_LEN);
@@ -148,45 +136,11 @@ static int max6900_i2c_write_regs(struct i2c_client *client, u8 const *buf)
148 136
149 return 0; 137 return 0;
150 138
151write_failed: 139 write_failed:
152 dev_err(&client->dev, "%s: register write failed\n", 140 dev_err(&client->dev, "%s: register write failed\n", __func__);
153 __func__);
154 return -EIO; 141 return -EIO;
155} 142}
156 143
157static int max6900_i2c_validate_client(struct i2c_client *client)
158{
159 u8 regs[MAX6900_REG_LEN];
160 u8 zero_mask[] = {
161 0x80, /* seconds */
162 0x80, /* minutes */
163 0x40, /* hours */
164 0xc0, /* day of month */
165 0xe0, /* month */
166 0xf8, /* day of week */
167 0x00, /* year */
168 0x7f, /* control */
169 };
170 int i;
171 int rc;
172 int reserved;
173
174 reserved = i2c_smbus_read_byte_data(client, MAX6900_REG_RESERVED_READ);
175 if (reserved != 0x07)
176 return -ENODEV;
177
178 rc = max6900_i2c_read_regs(client, regs);
179 if (rc < 0)
180 return rc;
181
182 for (i = 0; i < ARRAY_SIZE(zero_mask); ++i) {
183 if (regs[i] & zero_mask[i])
184 return -ENODEV;
185 }
186
187 return 0;
188}
189
190static int max6900_i2c_read_time(struct i2c_client *client, struct rtc_time *tm) 144static int max6900_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
191{ 145{
192 int rc; 146 int rc;
@@ -202,7 +156,7 @@ static int max6900_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
202 tm->tm_mday = BCD2BIN(regs[MAX6900_REG_DT]); 156 tm->tm_mday = BCD2BIN(regs[MAX6900_REG_DT]);
203 tm->tm_mon = BCD2BIN(regs[MAX6900_REG_MO]) - 1; 157 tm->tm_mon = BCD2BIN(regs[MAX6900_REG_MO]) - 1;
204 tm->tm_year = BCD2BIN(regs[MAX6900_REG_YR]) + 158 tm->tm_year = BCD2BIN(regs[MAX6900_REG_YR]) +
205 BCD2BIN(regs[MAX6900_REG_CENTURY]) * 100 - 1900; 159 BCD2BIN(regs[MAX6900_REG_CENTURY]) * 100 - 1900;
206 tm->tm_wday = BCD2BIN(regs[MAX6900_REG_DW]); 160 tm->tm_wday = BCD2BIN(regs[MAX6900_REG_DW]);
207 161
208 return 0; 162 return 0;
@@ -211,7 +165,7 @@ static int max6900_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
211static int max6900_i2c_clear_write_protect(struct i2c_client *client) 165static int max6900_i2c_clear_write_protect(struct i2c_client *client)
212{ 166{
213 int rc; 167 int rc;
214 rc = i2c_smbus_write_byte_data (client, MAX6900_REG_CONTROL_WRITE, 0); 168 rc = i2c_smbus_write_byte_data(client, MAX6900_REG_CONTROL_WRITE, 0);
215 if (rc < 0) { 169 if (rc < 0) {
216 dev_err(&client->dev, "%s: control register write failed\n", 170 dev_err(&client->dev, "%s: control register write failed\n",
217 __func__); 171 __func__);
@@ -220,8 +174,8 @@ static int max6900_i2c_clear_write_protect(struct i2c_client *client)
220 return 0; 174 return 0;
221} 175}
222 176
223static int max6900_i2c_set_time(struct i2c_client *client, 177static int
224 struct rtc_time const *tm) 178max6900_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)
225{ 179{
226 u8 regs[MAX6900_REG_LEN]; 180 u8 regs[MAX6900_REG_LEN];
227 int rc; 181 int rc;
@@ -258,89 +212,49 @@ static int max6900_rtc_set_time(struct device *dev, struct rtc_time *tm)
258 return max6900_i2c_set_time(to_i2c_client(dev), tm); 212 return max6900_i2c_set_time(to_i2c_client(dev), tm);
259} 213}
260 214
261static int max6900_attach_adapter(struct i2c_adapter *adapter) 215static int max6900_remove(struct i2c_client *client)
262{
263 return i2c_probe(adapter, &addr_data, max6900_probe);
264}
265
266static int max6900_detach_client(struct i2c_client *client)
267{ 216{
268 struct rtc_device *const rtc = i2c_get_clientdata(client); 217 struct rtc_device *rtc = i2c_get_clientdata(client);
269 218
270 if (rtc) 219 if (rtc)
271 rtc_device_unregister(rtc); 220 rtc_device_unregister(rtc);
272 221
273 return i2c_detach_client(client); 222 return 0;
274} 223}
275 224
276static struct i2c_driver max6900_driver = {
277 .driver = {
278 .name = DRV_NAME,
279 },
280 .id = I2C_DRIVERID_MAX6900,
281 .attach_adapter = max6900_attach_adapter,
282 .detach_client = max6900_detach_client,
283};
284
285static const struct rtc_class_ops max6900_rtc_ops = { 225static const struct rtc_class_ops max6900_rtc_ops = {
286 .read_time = max6900_rtc_read_time, 226 .read_time = max6900_rtc_read_time,
287 .set_time = max6900_rtc_set_time, 227 .set_time = max6900_rtc_set_time,
288}; 228};
289 229
290static int max6900_probe(struct i2c_adapter *adapter, int addr, int kind) 230static int
231max6900_probe(struct i2c_client *client, const struct i2c_device_id *id)
291{ 232{
292 int rc = 0; 233 struct rtc_device *rtc;
293 struct i2c_client *client = NULL;
294 struct rtc_device *rtc = NULL;
295
296 if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
297 rc = -ENODEV;
298 goto failout;
299 }
300
301 client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
302 if (client == NULL) {
303 rc = -ENOMEM;
304 goto failout;
305 }
306
307 client->addr = addr;
308 client->adapter = adapter;
309 client->driver = &max6900_driver;
310 strlcpy(client->name, DRV_NAME, I2C_NAME_SIZE);
311
312 if (kind < 0) {
313 rc = max6900_i2c_validate_client(client);
314 if (rc < 0)
315 goto failout;
316 }
317 234
318 rc = i2c_attach_client(client); 235 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
319 if (rc < 0) 236 return -ENODEV;
320 goto failout;
321 237
322 dev_info(&client->dev, 238 dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
323 "chip found, driver version " DRV_VERSION "\n");
324 239
325 rtc = rtc_device_register(max6900_driver.driver.name, 240 rtc = rtc_device_register(max6900_driver.driver.name,
326 &client->dev, 241 &client->dev, &max6900_rtc_ops, THIS_MODULE);
327 &max6900_rtc_ops, THIS_MODULE); 242 if (IS_ERR(rtc))
328 if (IS_ERR(rtc)) { 243 return PTR_ERR(rtc);
329 rc = PTR_ERR(rtc);
330 goto failout_detach;
331 }
332 244
333 i2c_set_clientdata(client, rtc); 245 i2c_set_clientdata(client, rtc);
334 246
335 return 0; 247 return 0;
336
337failout_detach:
338 i2c_detach_client(client);
339failout:
340 kfree(client);
341 return rc;
342} 248}
343 249
250static struct i2c_driver max6900_driver = {
251 .driver = {
252 .name = "rtc-max6900",
253 },
254 .probe = max6900_probe,
255 .remove = max6900_remove,
256};
257
344static int __init max6900_init(void) 258static int __init max6900_init(void)
345{ 259{
346 return i2c_add_driver(&max6900_driver); 260 return i2c_add_driver(&max6900_driver);
@@ -352,6 +266,7 @@ static void __exit max6900_exit(void)
352} 266}
353 267
354MODULE_DESCRIPTION("Maxim MAX6900 RTC driver"); 268MODULE_DESCRIPTION("Maxim MAX6900 RTC driver");
269MODULE_AUTHOR("Dale Farnsworth <dale@farnsworth.org>");
355MODULE_LICENSE("GPL"); 270MODULE_LICENSE("GPL");
356MODULE_VERSION(DRV_VERSION); 271MODULE_VERSION(DRV_VERSION);
357 272
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c
index 748a502a6355..a829f20ad6d6 100644
--- a/drivers/rtc/rtc-pcf8563.c
+++ b/drivers/rtc/rtc-pcf8563.c
@@ -179,58 +179,6 @@ struct pcf8563_limit
179 unsigned char max; 179 unsigned char max;
180}; 180};
181 181
182static int pcf8563_validate_client(struct i2c_client *client)
183{
184 int i;
185
186 static const struct pcf8563_limit pattern[] = {
187 /* register, mask, min, max */
188 { PCF8563_REG_SC, 0x7F, 0, 59 },
189 { PCF8563_REG_MN, 0x7F, 0, 59 },
190 { PCF8563_REG_HR, 0x3F, 0, 23 },
191 { PCF8563_REG_DM, 0x3F, 0, 31 },
192 { PCF8563_REG_MO, 0x1F, 0, 12 },
193 };
194
195 /* check limits (only registers with bcd values) */
196 for (i = 0; i < ARRAY_SIZE(pattern); i++) {
197 int xfer;
198 unsigned char value;
199 unsigned char buf = pattern[i].reg;
200
201 struct i2c_msg msgs[] = {
202 { client->addr, 0, 1, &buf },
203 { client->addr, I2C_M_RD, 1, &buf },
204 };
205
206 xfer = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
207
208 if (xfer != ARRAY_SIZE(msgs)) {
209 dev_err(&client->dev,
210 "%s: could not read register 0x%02X\n",
211 __func__, pattern[i].reg);
212
213 return -EIO;
214 }
215
216 value = BCD2BIN(buf & pattern[i].mask);
217
218 if (value > pattern[i].max ||
219 value < pattern[i].min) {
220 dev_dbg(&client->dev,
221 "%s: pattern=%d, reg=%x, mask=0x%02x, min=%d, "
222 "max=%d, value=%d, raw=0x%02X\n",
223 __func__, i, pattern[i].reg, pattern[i].mask,
224 pattern[i].min, pattern[i].max,
225 value, buf);
226
227 return -ENODEV;
228 }
229 }
230
231 return 0;
232}
233
234static int pcf8563_rtc_read_time(struct device *dev, struct rtc_time *tm) 182static int pcf8563_rtc_read_time(struct device *dev, struct rtc_time *tm)
235{ 183{
236 return pcf8563_get_datetime(to_i2c_client(dev), tm); 184 return pcf8563_get_datetime(to_i2c_client(dev), tm);
@@ -262,12 +210,6 @@ static int pcf8563_probe(struct i2c_client *client,
262 if (!pcf8563) 210 if (!pcf8563)
263 return -ENOMEM; 211 return -ENOMEM;
264 212
265 /* Verify the chip is really an PCF8563 */
266 if (pcf8563_validate_client(client) < 0) {
267 err = -ENODEV;
268 goto exit_kfree;
269 }
270
271 dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); 213 dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
272 214
273 pcf8563->rtc = rtc_device_register(pcf8563_driver.driver.name, 215 pcf8563->rtc = rtc_device_register(pcf8563_driver.driver.name,
diff --git a/drivers/rtc/rtc-pl030.c b/drivers/rtc/rtc-pl030.c
index 8448eeb9d675..826153552157 100644
--- a/drivers/rtc/rtc-pl030.c
+++ b/drivers/rtc/rtc-pl030.c
@@ -34,15 +34,6 @@ static irqreturn_t pl030_interrupt(int irq, void *dev_id)
34 return IRQ_HANDLED; 34 return IRQ_HANDLED;
35} 35}
36 36
37static int pl030_open(struct device *dev)
38{
39 return 0;
40}
41
42static void pl030_release(struct device *dev)
43{
44}
45
46static int pl030_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) 37static int pl030_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
47{ 38{
48 return -ENOIOCTLCMD; 39 return -ENOIOCTLCMD;
@@ -104,8 +95,6 @@ static int pl030_set_time(struct device *dev, struct rtc_time *tm)
104} 95}
105 96
106static const struct rtc_class_ops pl030_ops = { 97static const struct rtc_class_ops pl030_ops = {
107 .open = pl030_open,
108 .release = pl030_release,
109 .ioctl = pl030_ioctl, 98 .ioctl = pl030_ioctl,
110 .read_time = pl030_read_time, 99 .read_time = pl030_read_time,
111 .set_time = pl030_set_time, 100 .set_time = pl030_set_time,
diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c
index 08b4610ec5a6..333eec689d2f 100644
--- a/drivers/rtc/rtc-pl031.c
+++ b/drivers/rtc/rtc-pl031.c
@@ -45,18 +45,6 @@ static irqreturn_t pl031_interrupt(int irq, void *dev_id)
45 return IRQ_HANDLED; 45 return IRQ_HANDLED;
46} 46}
47 47
48static int pl031_open(struct device *dev)
49{
50 /*
51 * We request IRQ in pl031_probe, so nothing to do here...
52 */
53 return 0;
54}
55
56static void pl031_release(struct device *dev)
57{
58}
59
60static int pl031_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) 48static int pl031_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
61{ 49{
62 struct pl031_local *ldata = dev_get_drvdata(dev); 50 struct pl031_local *ldata = dev_get_drvdata(dev);
@@ -118,8 +106,6 @@ static int pl031_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
118} 106}
119 107
120static const struct rtc_class_ops pl031_ops = { 108static const struct rtc_class_ops pl031_ops = {
121 .open = pl031_open,
122 .release = pl031_release,
123 .ioctl = pl031_ioctl, 109 .ioctl = pl031_ioctl,
124 .read_time = pl031_read_time, 110 .read_time = pl031_read_time,
125 .set_time = pl031_set_time, 111 .set_time = pl031_set_time,
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c
index 56caf6b2c3e5..8b561958fb1e 100644
--- a/drivers/rtc/rtc-rs5c372.c
+++ b/drivers/rtc/rtc-rs5c372.c
@@ -1,8 +1,9 @@
1/* 1/*
2 * An I2C driver for Ricoh RS5C372 and RV5C38[67] RTCs 2 * An I2C driver for Ricoh RS5C372, R2025S/D and RV5C38[67] RTCs
3 * 3 *
4 * Copyright (C) 2005 Pavel Mironchik <pmironchik@optifacio.net> 4 * Copyright (C) 2005 Pavel Mironchik <pmironchik@optifacio.net>
5 * Copyright (C) 2006 Tower Technologies 5 * Copyright (C) 2006 Tower Technologies
6 * Copyright (C) 2008 Paul Mundt
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
@@ -13,7 +14,7 @@
13#include <linux/rtc.h> 14#include <linux/rtc.h>
14#include <linux/bcd.h> 15#include <linux/bcd.h>
15 16
16#define DRV_VERSION "0.5" 17#define DRV_VERSION "0.6"
17 18
18 19
19/* 20/*
@@ -51,7 +52,8 @@
51# define RS5C_CTRL1_CT4 (4 << 0) /* 1 Hz level irq */ 52# define RS5C_CTRL1_CT4 (4 << 0) /* 1 Hz level irq */
52#define RS5C_REG_CTRL2 15 53#define RS5C_REG_CTRL2 15
53# define RS5C372_CTRL2_24 (1 << 5) 54# define RS5C372_CTRL2_24 (1 << 5)
54# define RS5C_CTRL2_XSTP (1 << 4) 55# define R2025_CTRL2_XST (1 << 5)
56# define RS5C_CTRL2_XSTP (1 << 4) /* only if !R2025S/D */
55# define RS5C_CTRL2_CTFG (1 << 2) 57# define RS5C_CTRL2_CTFG (1 << 2)
56# define RS5C_CTRL2_AAFG (1 << 1) /* or WAFG */ 58# define RS5C_CTRL2_AAFG (1 << 1) /* or WAFG */
57# define RS5C_CTRL2_BAFG (1 << 0) /* or DAFG */ 59# define RS5C_CTRL2_BAFG (1 << 0) /* or DAFG */
@@ -63,6 +65,7 @@
63 65
64enum rtc_type { 66enum rtc_type {
65 rtc_undef = 0, 67 rtc_undef = 0,
68 rtc_r2025sd,
66 rtc_rs5c372a, 69 rtc_rs5c372a,
67 rtc_rs5c372b, 70 rtc_rs5c372b,
68 rtc_rv5c386, 71 rtc_rv5c386,
@@ -70,6 +73,7 @@ enum rtc_type {
70}; 73};
71 74
72static const struct i2c_device_id rs5c372_id[] = { 75static const struct i2c_device_id rs5c372_id[] = {
76 { "r2025sd", rtc_r2025sd },
73 { "rs5c372a", rtc_rs5c372a }, 77 { "rs5c372a", rtc_rs5c372a },
74 { "rs5c372b", rtc_rs5c372b }, 78 { "rs5c372b", rtc_rs5c372b },
75 { "rv5c386", rtc_rv5c386 }, 79 { "rv5c386", rtc_rv5c386 },
@@ -89,6 +93,7 @@ struct rs5c372 {
89 enum rtc_type type; 93 enum rtc_type type;
90 unsigned time24:1; 94 unsigned time24:1;
91 unsigned has_irq:1; 95 unsigned has_irq:1;
96 unsigned smbus:1;
92 char buf[17]; 97 char buf[17];
93 char *regs; 98 char *regs;
94}; 99};
@@ -106,10 +111,25 @@ static int rs5c_get_regs(struct rs5c372 *rs5c)
106 * 111 *
107 * The first method doesn't work with the iop3xx adapter driver, on at 112 * The first method doesn't work with the iop3xx adapter driver, on at
108 * least 80219 chips; this works around that bug. 113 * least 80219 chips; this works around that bug.
114 *
115 * The third method on the other hand doesn't work for the SMBus-only
116 * configurations, so we use the the first method there, stripping off
117 * the extra register in the process.
109 */ 118 */
110 if ((i2c_transfer(client->adapter, msgs, 1)) != 1) { 119 if (rs5c->smbus) {
111 dev_warn(&client->dev, "can't read registers\n"); 120 int addr = RS5C_ADDR(RS5C372_REG_SECS);
112 return -EIO; 121 int size = sizeof(rs5c->buf) - 1;
122
123 if (i2c_smbus_read_i2c_block_data(client, addr, size,
124 rs5c->buf + 1) != size) {
125 dev_warn(&client->dev, "can't read registers\n");
126 return -EIO;
127 }
128 } else {
129 if ((i2c_transfer(client->adapter, msgs, 1)) != 1) {
130 dev_warn(&client->dev, "can't read registers\n");
131 return -EIO;
132 }
113 } 133 }
114 134
115 dev_dbg(&client->dev, 135 dev_dbg(&client->dev,
@@ -187,6 +207,7 @@ static int rs5c372_set_datetime(struct i2c_client *client, struct rtc_time *tm)
187{ 207{
188 struct rs5c372 *rs5c = i2c_get_clientdata(client); 208 struct rs5c372 *rs5c = i2c_get_clientdata(client);
189 unsigned char buf[8]; 209 unsigned char buf[8];
210 int addr;
190 211
191 dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d " 212 dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d "
192 "mday=%d, mon=%d, year=%d, wday=%d\n", 213 "mday=%d, mon=%d, year=%d, wday=%d\n",
@@ -194,16 +215,16 @@ static int rs5c372_set_datetime(struct i2c_client *client, struct rtc_time *tm)
194 tm->tm_sec, tm->tm_min, tm->tm_hour, 215 tm->tm_sec, tm->tm_min, tm->tm_hour,
195 tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); 216 tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
196 217
197 buf[0] = RS5C_ADDR(RS5C372_REG_SECS); 218 addr = RS5C_ADDR(RS5C372_REG_SECS);
198 buf[1] = BIN2BCD(tm->tm_sec); 219 buf[0] = BIN2BCD(tm->tm_sec);
199 buf[2] = BIN2BCD(tm->tm_min); 220 buf[1] = BIN2BCD(tm->tm_min);
200 buf[3] = rs5c_hr2reg(rs5c, tm->tm_hour); 221 buf[2] = rs5c_hr2reg(rs5c, tm->tm_hour);
201 buf[4] = BIN2BCD(tm->tm_wday); 222 buf[3] = BIN2BCD(tm->tm_wday);
202 buf[5] = BIN2BCD(tm->tm_mday); 223 buf[4] = BIN2BCD(tm->tm_mday);
203 buf[6] = BIN2BCD(tm->tm_mon + 1); 224 buf[5] = BIN2BCD(tm->tm_mon + 1);
204 buf[7] = BIN2BCD(tm->tm_year - 100); 225 buf[6] = BIN2BCD(tm->tm_year - 100);
205 226
206 if ((i2c_master_send(client, buf, 8)) != 8) { 227 if (i2c_smbus_write_i2c_block_data(client, addr, sizeof(buf), buf) < 0) {
207 dev_err(&client->dev, "%s: write error\n", __func__); 228 dev_err(&client->dev, "%s: write error\n", __func__);
208 return -EIO; 229 return -EIO;
209 } 230 }
@@ -266,16 +287,16 @@ rs5c_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
266{ 287{
267 struct i2c_client *client = to_i2c_client(dev); 288 struct i2c_client *client = to_i2c_client(dev);
268 struct rs5c372 *rs5c = i2c_get_clientdata(client); 289 struct rs5c372 *rs5c = i2c_get_clientdata(client);
269 unsigned char buf[2]; 290 unsigned char buf;
270 int status; 291 int status, addr;
271 292
272 buf[1] = rs5c->regs[RS5C_REG_CTRL1]; 293 buf = rs5c->regs[RS5C_REG_CTRL1];
273 switch (cmd) { 294 switch (cmd) {
274 case RTC_UIE_OFF: 295 case RTC_UIE_OFF:
275 case RTC_UIE_ON: 296 case RTC_UIE_ON:
276 /* some 327a modes use a different IRQ pin for 1Hz irqs */ 297 /* some 327a modes use a different IRQ pin for 1Hz irqs */
277 if (rs5c->type == rtc_rs5c372a 298 if (rs5c->type == rtc_rs5c372a
278 && (buf[1] & RS5C372A_CTRL1_SL1)) 299 && (buf & RS5C372A_CTRL1_SL1))
279 return -ENOIOCTLCMD; 300 return -ENOIOCTLCMD;
280 case RTC_AIE_OFF: 301 case RTC_AIE_OFF:
281 case RTC_AIE_ON: 302 case RTC_AIE_ON:
@@ -293,28 +314,30 @@ rs5c_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
293 if (status < 0) 314 if (status < 0)
294 return status; 315 return status;
295 316
296 buf[0] = RS5C_ADDR(RS5C_REG_CTRL1); 317 addr = RS5C_ADDR(RS5C_REG_CTRL1);
297 switch (cmd) { 318 switch (cmd) {
298 case RTC_AIE_OFF: /* alarm off */ 319 case RTC_AIE_OFF: /* alarm off */
299 buf[1] &= ~RS5C_CTRL1_AALE; 320 buf &= ~RS5C_CTRL1_AALE;
300 break; 321 break;
301 case RTC_AIE_ON: /* alarm on */ 322 case RTC_AIE_ON: /* alarm on */
302 buf[1] |= RS5C_CTRL1_AALE; 323 buf |= RS5C_CTRL1_AALE;
303 break; 324 break;
304 case RTC_UIE_OFF: /* update off */ 325 case RTC_UIE_OFF: /* update off */
305 buf[1] &= ~RS5C_CTRL1_CT_MASK; 326 buf &= ~RS5C_CTRL1_CT_MASK;
306 break; 327 break;
307 case RTC_UIE_ON: /* update on */ 328 case RTC_UIE_ON: /* update on */
308 buf[1] &= ~RS5C_CTRL1_CT_MASK; 329 buf &= ~RS5C_CTRL1_CT_MASK;
309 buf[1] |= RS5C_CTRL1_CT4; 330 buf |= RS5C_CTRL1_CT4;
310 break; 331 break;
311 } 332 }
312 if ((i2c_master_send(client, buf, 2)) != 2) { 333
334 if (i2c_smbus_write_byte_data(client, addr, buf) < 0) {
313 printk(KERN_WARNING "%s: can't update alarm\n", 335 printk(KERN_WARNING "%s: can't update alarm\n",
314 rs5c->rtc->name); 336 rs5c->rtc->name);
315 status = -EIO; 337 status = -EIO;
316 } else 338 } else
317 rs5c->regs[RS5C_REG_CTRL1] = buf[1]; 339 rs5c->regs[RS5C_REG_CTRL1] = buf;
340
318 return status; 341 return status;
319} 342}
320 343
@@ -364,8 +387,8 @@ static int rs5c_set_alarm(struct device *dev, struct rtc_wkalrm *t)
364{ 387{
365 struct i2c_client *client = to_i2c_client(dev); 388 struct i2c_client *client = to_i2c_client(dev);
366 struct rs5c372 *rs5c = i2c_get_clientdata(client); 389 struct rs5c372 *rs5c = i2c_get_clientdata(client);
367 int status; 390 int status, addr, i;
368 unsigned char buf[4]; 391 unsigned char buf[3];
369 392
370 /* only handle up to 24 hours in the future, like RTC_ALM_SET */ 393 /* only handle up to 24 hours in the future, like RTC_ALM_SET */
371 if (t->time.tm_mday != -1 394 if (t->time.tm_mday != -1
@@ -380,33 +403,36 @@ static int rs5c_set_alarm(struct device *dev, struct rtc_wkalrm *t)
380 if (status < 0) 403 if (status < 0)
381 return status; 404 return status;
382 if (rs5c->regs[RS5C_REG_CTRL1] & RS5C_CTRL1_AALE) { 405 if (rs5c->regs[RS5C_REG_CTRL1] & RS5C_CTRL1_AALE) {
383 buf[0] = RS5C_ADDR(RS5C_REG_CTRL1); 406 addr = RS5C_ADDR(RS5C_REG_CTRL1);
384 buf[1] = rs5c->regs[RS5C_REG_CTRL1] & ~RS5C_CTRL1_AALE; 407 buf[0] = rs5c->regs[RS5C_REG_CTRL1] & ~RS5C_CTRL1_AALE;
385 if (i2c_master_send(client, buf, 2) != 2) { 408 if (i2c_smbus_write_byte_data(client, addr, buf[0]) < 0) {
386 pr_debug("%s: can't disable alarm\n", rs5c->rtc->name); 409 pr_debug("%s: can't disable alarm\n", rs5c->rtc->name);
387 return -EIO; 410 return -EIO;
388 } 411 }
389 rs5c->regs[RS5C_REG_CTRL1] = buf[1]; 412 rs5c->regs[RS5C_REG_CTRL1] = buf[0];
390 } 413 }
391 414
392 /* set alarm */ 415 /* set alarm */
393 buf[0] = RS5C_ADDR(RS5C_REG_ALARM_A_MIN); 416 buf[0] = BIN2BCD(t->time.tm_min);
394 buf[1] = BIN2BCD(t->time.tm_min); 417 buf[1] = rs5c_hr2reg(rs5c, t->time.tm_hour);
395 buf[2] = rs5c_hr2reg(rs5c, t->time.tm_hour); 418 buf[2] = 0x7f; /* any/all days */
396 buf[3] = 0x7f; /* any/all days */ 419
397 if ((i2c_master_send(client, buf, 4)) != 4) { 420 for (i = 0; i < sizeof(buf); i++) {
398 pr_debug("%s: can't set alarm time\n", rs5c->rtc->name); 421 addr = RS5C_ADDR(RS5C_REG_ALARM_A_MIN + i);
399 return -EIO; 422 if (i2c_smbus_write_byte_data(client, addr, buf[i]) < 0) {
423 pr_debug("%s: can't set alarm time\n", rs5c->rtc->name);
424 return -EIO;
425 }
400 } 426 }
401 427
402 /* ... and maybe enable its irq */ 428 /* ... and maybe enable its irq */
403 if (t->enabled) { 429 if (t->enabled) {
404 buf[0] = RS5C_ADDR(RS5C_REG_CTRL1); 430 addr = RS5C_ADDR(RS5C_REG_CTRL1);
405 buf[1] = rs5c->regs[RS5C_REG_CTRL1] | RS5C_CTRL1_AALE; 431 buf[0] = rs5c->regs[RS5C_REG_CTRL1] | RS5C_CTRL1_AALE;
406 if ((i2c_master_send(client, buf, 2)) != 2) 432 if (i2c_smbus_write_byte_data(client, addr, buf[0]) < 0)
407 printk(KERN_WARNING "%s: can't enable alarm\n", 433 printk(KERN_WARNING "%s: can't enable alarm\n",
408 rs5c->rtc->name); 434 rs5c->rtc->name);
409 rs5c->regs[RS5C_REG_CTRL1] = buf[1]; 435 rs5c->regs[RS5C_REG_CTRL1] = buf[0];
410 } 436 }
411 437
412 return 0; 438 return 0;
@@ -503,18 +529,81 @@ static void rs5c_sysfs_unregister(struct device *dev)
503 529
504static struct i2c_driver rs5c372_driver; 530static struct i2c_driver rs5c372_driver;
505 531
532static int rs5c_oscillator_setup(struct rs5c372 *rs5c372)
533{
534 unsigned char buf[2];
535 int addr, i, ret = 0;
536
537 if (rs5c372->type == rtc_r2025sd) {
538 if (!(rs5c372->regs[RS5C_REG_CTRL2] & R2025_CTRL2_XST))
539 return ret;
540 rs5c372->regs[RS5C_REG_CTRL2] &= ~R2025_CTRL2_XST;
541 } else {
542 if (!(rs5c372->regs[RS5C_REG_CTRL2] & RS5C_CTRL2_XSTP))
543 return ret;
544 rs5c372->regs[RS5C_REG_CTRL2] &= ~RS5C_CTRL2_XSTP;
545 }
546
547 addr = RS5C_ADDR(RS5C_REG_CTRL1);
548 buf[0] = rs5c372->regs[RS5C_REG_CTRL1];
549 buf[1] = rs5c372->regs[RS5C_REG_CTRL2];
550
551 /* use 24hr mode */
552 switch (rs5c372->type) {
553 case rtc_rs5c372a:
554 case rtc_rs5c372b:
555 buf[1] |= RS5C372_CTRL2_24;
556 rs5c372->time24 = 1;
557 break;
558 case rtc_r2025sd:
559 case rtc_rv5c386:
560 case rtc_rv5c387a:
561 buf[0] |= RV5C387_CTRL1_24;
562 rs5c372->time24 = 1;
563 break;
564 default:
565 /* impossible */
566 break;
567 }
568
569 for (i = 0; i < sizeof(buf); i++) {
570 addr = RS5C_ADDR(RS5C_REG_CTRL1 + i);
571 ret = i2c_smbus_write_byte_data(rs5c372->client, addr, buf[i]);
572 if (unlikely(ret < 0))
573 return ret;
574 }
575
576 rs5c372->regs[RS5C_REG_CTRL1] = buf[0];
577 rs5c372->regs[RS5C_REG_CTRL2] = buf[1];
578
579 return 0;
580}
581
506static int rs5c372_probe(struct i2c_client *client, 582static int rs5c372_probe(struct i2c_client *client,
507 const struct i2c_device_id *id) 583 const struct i2c_device_id *id)
508{ 584{
509 int err = 0; 585 int err = 0;
586 int smbus_mode = 0;
510 struct rs5c372 *rs5c372; 587 struct rs5c372 *rs5c372;
511 struct rtc_time tm; 588 struct rtc_time tm;
512 589
513 dev_dbg(&client->dev, "%s\n", __func__); 590 dev_dbg(&client->dev, "%s\n", __func__);
514 591
515 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 592 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
516 err = -ENODEV; 593 I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_I2C_BLOCK)) {
517 goto exit; 594 /*
595 * If we don't have any master mode adapter, try breaking
596 * it down in to the barest of capabilities.
597 */
598 if (i2c_check_functionality(client->adapter,
599 I2C_FUNC_SMBUS_BYTE_DATA |
600 I2C_FUNC_SMBUS_I2C_BLOCK))
601 smbus_mode = 1;
602 else {
603 /* Still no good, give up */
604 err = -ENODEV;
605 goto exit;
606 }
518 } 607 }
519 608
520 if (!(rs5c372 = kzalloc(sizeof(struct rs5c372), GFP_KERNEL))) { 609 if (!(rs5c372 = kzalloc(sizeof(struct rs5c372), GFP_KERNEL))) {
@@ -528,6 +617,7 @@ static int rs5c372_probe(struct i2c_client *client,
528 617
529 /* we read registers 0x0f then 0x00-0x0f; skip the first one */ 618 /* we read registers 0x0f then 0x00-0x0f; skip the first one */
530 rs5c372->regs = &rs5c372->buf[1]; 619 rs5c372->regs = &rs5c372->buf[1];
620 rs5c372->smbus = smbus_mode;
531 621
532 err = rs5c_get_regs(rs5c372); 622 err = rs5c_get_regs(rs5c372);
533 if (err < 0) 623 if (err < 0)
@@ -543,6 +633,7 @@ static int rs5c372_probe(struct i2c_client *client,
543 if (rs5c372->regs[RS5C_REG_CTRL2] & RS5C372_CTRL2_24) 633 if (rs5c372->regs[RS5C_REG_CTRL2] & RS5C372_CTRL2_24)
544 rs5c372->time24 = 1; 634 rs5c372->time24 = 1;
545 break; 635 break;
636 case rtc_r2025sd:
546 case rtc_rv5c386: 637 case rtc_rv5c386:
547 case rtc_rv5c387a: 638 case rtc_rv5c387a:
548 if (rs5c372->regs[RS5C_REG_CTRL1] & RV5C387_CTRL1_24) 639 if (rs5c372->regs[RS5C_REG_CTRL1] & RV5C387_CTRL1_24)
@@ -558,39 +649,14 @@ static int rs5c372_probe(struct i2c_client *client,
558 649
559 /* if the oscillator lost power and no other software (like 650 /* if the oscillator lost power and no other software (like
560 * the bootloader) set it up, do it here. 651 * the bootloader) set it up, do it here.
652 *
653 * The R2025S/D does this a little differently than the other
654 * parts, so we special case that..
561 */ 655 */
562 if (rs5c372->regs[RS5C_REG_CTRL2] & RS5C_CTRL2_XSTP) { 656 err = rs5c_oscillator_setup(rs5c372);
563 unsigned char buf[3]; 657 if (unlikely(err < 0)) {
564 658 dev_err(&client->dev, "setup error\n");
565 rs5c372->regs[RS5C_REG_CTRL2] &= ~RS5C_CTRL2_XSTP; 659 goto exit_kfree;
566
567 buf[0] = RS5C_ADDR(RS5C_REG_CTRL1);
568 buf[1] = rs5c372->regs[RS5C_REG_CTRL1];
569 buf[2] = rs5c372->regs[RS5C_REG_CTRL2];
570
571 /* use 24hr mode */
572 switch (rs5c372->type) {
573 case rtc_rs5c372a:
574 case rtc_rs5c372b:
575 buf[2] |= RS5C372_CTRL2_24;
576 rs5c372->time24 = 1;
577 break;
578 case rtc_rv5c386:
579 case rtc_rv5c387a:
580 buf[1] |= RV5C387_CTRL1_24;
581 rs5c372->time24 = 1;
582 break;
583 default:
584 /* impossible */
585 break;
586 }
587
588 if ((i2c_master_send(client, buf, 3)) != 3) {
589 dev_err(&client->dev, "setup error\n");
590 goto exit_kfree;
591 }
592 rs5c372->regs[RS5C_REG_CTRL1] = buf[1];
593 rs5c372->regs[RS5C_REG_CTRL2] = buf[2];
594 } 660 }
595 661
596 if (rs5c372_get_datetime(client, &tm) < 0) 662 if (rs5c372_get_datetime(client, &tm) < 0)
@@ -598,6 +664,7 @@ static int rs5c372_probe(struct i2c_client *client,
598 664
599 dev_info(&client->dev, "%s found, %s, driver version " DRV_VERSION "\n", 665 dev_info(&client->dev, "%s found, %s, driver version " DRV_VERSION "\n",
600 ({ char *s; switch (rs5c372->type) { 666 ({ char *s; switch (rs5c372->type) {
667 case rtc_r2025sd: s = "r2025sd"; break;
601 case rtc_rs5c372a: s = "rs5c372a"; break; 668 case rtc_rs5c372a: s = "rs5c372a"; break;
602 case rtc_rs5c372b: s = "rs5c372b"; break; 669 case rtc_rs5c372b: s = "rs5c372b"; break;
603 case rtc_rv5c386: s = "rv5c386"; break; 670 case rtc_rv5c386: s = "rv5c386"; break;
@@ -667,7 +734,8 @@ module_exit(rs5c372_exit);
667 734
668MODULE_AUTHOR( 735MODULE_AUTHOR(
669 "Pavel Mironchik <pmironchik@optifacio.net>, " 736 "Pavel Mironchik <pmironchik@optifacio.net>, "
670 "Alessandro Zummo <a.zummo@towertech.it>"); 737 "Alessandro Zummo <a.zummo@towertech.it>, "
738 "Paul Mundt <lethal@linux-sh.org>");
671MODULE_DESCRIPTION("Ricoh RS5C372 RTC driver"); 739MODULE_DESCRIPTION("Ricoh RS5C372 RTC driver");
672MODULE_LICENSE("GPL"); 740MODULE_LICENSE("GPL");
673MODULE_VERSION(DRV_VERSION); 741MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c
index 1f88e9e914ec..fcead4c4cd1f 100644
--- a/drivers/rtc/rtc-sh.c
+++ b/drivers/rtc/rtc-sh.c
@@ -257,12 +257,6 @@ static inline void sh_rtc_setaie(struct device *dev, unsigned int enable)
257 spin_unlock_irq(&rtc->lock); 257 spin_unlock_irq(&rtc->lock);
258} 258}
259 259
260static void sh_rtc_release(struct device *dev)
261{
262 sh_rtc_setpie(dev, 0);
263 sh_rtc_setaie(dev, 0);
264}
265
266static int sh_rtc_proc(struct device *dev, struct seq_file *seq) 260static int sh_rtc_proc(struct device *dev, struct seq_file *seq)
267{ 261{
268 struct sh_rtc *rtc = dev_get_drvdata(dev); 262 struct sh_rtc *rtc = dev_get_drvdata(dev);
@@ -559,7 +553,6 @@ static int sh_rtc_irq_set_freq(struct device *dev, int freq)
559} 553}
560 554
561static struct rtc_class_ops sh_rtc_ops = { 555static struct rtc_class_ops sh_rtc_ops = {
562 .release = sh_rtc_release,
563 .ioctl = sh_rtc_ioctl, 556 .ioctl = sh_rtc_ioctl,
564 .read_time = sh_rtc_read_time, 557 .read_time = sh_rtc_read_time,
565 .set_time = sh_rtc_set_time, 558 .set_time = sh_rtc_set_time,
diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c
index 31d3c8c28588..9a7e920315fa 100644
--- a/drivers/rtc/rtc-stk17ta8.c
+++ b/drivers/rtc/rtc-stk17ta8.c
@@ -215,17 +215,6 @@ static irqreturn_t stk17ta8_rtc_interrupt(int irq, void *dev_id)
215 return IRQ_HANDLED; 215 return IRQ_HANDLED;
216} 216}
217 217
218static void stk17ta8_rtc_release(struct device *dev)
219{
220 struct platform_device *pdev = to_platform_device(dev);
221 struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
222
223 if (pdata->irq >= 0) {
224 pdata->irqen = 0;
225 stk17ta8_rtc_update_alarm(pdata);
226 }
227}
228
229static int stk17ta8_rtc_ioctl(struct device *dev, unsigned int cmd, 218static int stk17ta8_rtc_ioctl(struct device *dev, unsigned int cmd,
230 unsigned long arg) 219 unsigned long arg)
231{ 220{
@@ -254,7 +243,6 @@ static const struct rtc_class_ops stk17ta8_rtc_ops = {
254 .set_time = stk17ta8_rtc_set_time, 243 .set_time = stk17ta8_rtc_set_time,
255 .read_alarm = stk17ta8_rtc_read_alarm, 244 .read_alarm = stk17ta8_rtc_read_alarm,
256 .set_alarm = stk17ta8_rtc_set_alarm, 245 .set_alarm = stk17ta8_rtc_set_alarm,
257 .release = stk17ta8_rtc_release,
258 .ioctl = stk17ta8_rtc_ioctl, 246 .ioctl = stk17ta8_rtc_ioctl,
259}; 247};
260 248
diff --git a/drivers/s390/net/ctcm_mpc.c b/drivers/s390/net/ctcm_mpc.c
index cbe470493bf0..19f5d5ed85e0 100644
--- a/drivers/s390/net/ctcm_mpc.c
+++ b/drivers/s390/net/ctcm_mpc.c
@@ -1673,7 +1673,7 @@ static int mpc_validate_xid(struct mpcg_info *mpcginfo)
1673 1673
1674done: 1674done:
1675 if (rc) { 1675 if (rc) {
1676 ctcm_pr_info("ctcmpc : %s() failed\n", __FUNCTION__); 1676 ctcm_pr_info("ctcmpc : %s() failed\n", __func__);
1677 priv->xid->xid2_flag2 = 0x40; 1677 priv->xid->xid2_flag2 = 0x40;
1678 grp->saved_xid2->xid2_flag2 = 0x40; 1678 grp->saved_xid2->xid2_flag2 = 0x40;
1679 } 1679 }
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index d3ca7d32abe0..1528de23a650 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -2223,9 +2223,9 @@ serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
2223 serial_outp(up, UART_EFR, efr); 2223 serial_outp(up, UART_EFR, efr);
2224 } 2224 }
2225 2225
2226#ifdef CONFIG_ARCH_OMAP15XX 2226#ifdef CONFIG_ARCH_OMAP
2227 /* Workaround to enable 115200 baud on OMAP1510 internal ports */ 2227 /* Workaround to enable 115200 baud on OMAP1510 internal ports */
2228 if (cpu_is_omap1510() && is_omap_port((unsigned int)up->port.membase)) { 2228 if (cpu_is_omap1510() && is_omap_port(up)) {
2229 if (baud == 115200) { 2229 if (baud == 115200) {
2230 quot = 1; 2230 quot = 1;
2231 serial_out(up, UART_OMAP_OSC_12M_SEL, 1); 2231 serial_out(up, UART_OMAP_OSC_12M_SEL, 1);
@@ -2278,18 +2278,27 @@ serial8250_pm(struct uart_port *port, unsigned int state,
2278 p->pm(port, state, oldstate); 2278 p->pm(port, state, oldstate);
2279} 2279}
2280 2280
2281static unsigned int serial8250_port_size(struct uart_8250_port *pt)
2282{
2283 if (pt->port.iotype == UPIO_AU)
2284 return 0x100000;
2285#ifdef CONFIG_ARCH_OMAP
2286 if (is_omap_port(pt))
2287 return 0x16 << pt->port.regshift;
2288#endif
2289 return 8 << pt->port.regshift;
2290}
2291
2281/* 2292/*
2282 * Resource handling. 2293 * Resource handling.
2283 */ 2294 */
2284static int serial8250_request_std_resource(struct uart_8250_port *up) 2295static int serial8250_request_std_resource(struct uart_8250_port *up)
2285{ 2296{
2286 unsigned int size = 8 << up->port.regshift; 2297 unsigned int size = serial8250_port_size(up);
2287 int ret = 0; 2298 int ret = 0;
2288 2299
2289 switch (up->port.iotype) { 2300 switch (up->port.iotype) {
2290 case UPIO_AU: 2301 case UPIO_AU:
2291 size = 0x100000;
2292 /* fall thru */
2293 case UPIO_TSI: 2302 case UPIO_TSI:
2294 case UPIO_MEM32: 2303 case UPIO_MEM32:
2295 case UPIO_MEM: 2304 case UPIO_MEM:
@@ -2323,12 +2332,10 @@ static int serial8250_request_std_resource(struct uart_8250_port *up)
2323 2332
2324static void serial8250_release_std_resource(struct uart_8250_port *up) 2333static void serial8250_release_std_resource(struct uart_8250_port *up)
2325{ 2334{
2326 unsigned int size = 8 << up->port.regshift; 2335 unsigned int size = serial8250_port_size(up);
2327 2336
2328 switch (up->port.iotype) { 2337 switch (up->port.iotype) {
2329 case UPIO_AU: 2338 case UPIO_AU:
2330 size = 0x100000;
2331 /* fall thru */
2332 case UPIO_TSI: 2339 case UPIO_TSI:
2333 case UPIO_MEM32: 2340 case UPIO_MEM32:
2334 case UPIO_MEM: 2341 case UPIO_MEM:
diff --git a/drivers/serial/s3c2400.c b/drivers/serial/s3c2400.c
index c8b4266ac35f..4873f2978bd2 100644
--- a/drivers/serial/s3c2400.c
+++ b/drivers/serial/s3c2400.c
@@ -19,7 +19,7 @@
19 19
20#include <mach/hardware.h> 20#include <mach/hardware.h>
21 21
22#include <asm/plat-s3c/regs-serial.h> 22#include <plat/regs-serial.h>
23#include <mach/regs-gpio.h> 23#include <mach/regs-gpio.h>
24 24
25#include "samsung.h" 25#include "samsung.h"
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index 40a2531b5541..87c182ef71b8 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -21,7 +21,7 @@
21#include <asm/irq.h> 21#include <asm/irq.h>
22#include <mach/hardware.h> 22#include <mach/hardware.h>
23 23
24#include <asm/plat-s3c/regs-serial.h> 24#include <plat/regs-serial.h>
25#include <mach/regs-gpio.h> 25#include <mach/regs-gpio.h>
26 26
27#include "samsung.h" 27#include "samsung.h"
diff --git a/drivers/serial/s3c2412.c b/drivers/serial/s3c2412.c
index d0170319c729..fd017b375568 100644
--- a/drivers/serial/s3c2412.c
+++ b/drivers/serial/s3c2412.c
@@ -21,7 +21,7 @@
21#include <asm/irq.h> 21#include <asm/irq.h>
22#include <mach/hardware.h> 22#include <mach/hardware.h>
23 23
24#include <asm/plat-s3c/regs-serial.h> 24#include <plat/regs-serial.h>
25#include <mach/regs-gpio.h> 25#include <mach/regs-gpio.h>
26 26
27#include "samsung.h" 27#include "samsung.h"
diff --git a/drivers/serial/s3c2440.c b/drivers/serial/s3c2440.c
index d4a2b17b2498..317d239ab740 100644
--- a/drivers/serial/s3c2440.c
+++ b/drivers/serial/s3c2440.c
@@ -21,7 +21,7 @@
21#include <asm/irq.h> 21#include <asm/irq.h>
22#include <mach/hardware.h> 22#include <mach/hardware.h>
23 23
24#include <asm/plat-s3c/regs-serial.h> 24#include <plat/regs-serial.h>
25#include <mach/regs-gpio.h> 25#include <mach/regs-gpio.h>
26 26
27#include "samsung.h" 27#include "samsung.h"
diff --git a/drivers/serial/samsung.c b/drivers/serial/samsung.c
index 5a88b3f9fe9b..1e219d3d0352 100644
--- a/drivers/serial/samsung.c
+++ b/drivers/serial/samsung.c
@@ -47,7 +47,7 @@
47 47
48#include <mach/hardware.h> 48#include <mach/hardware.h>
49 49
50#include <asm/plat-s3c/regs-serial.h> 50#include <plat/regs-serial.h>
51#include <mach/regs-gpio.h> 51#include <mach/regs-gpio.h>
52 52
53#include "samsung.h" 53#include "samsung.h"
diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c
index cdb3d3191719..0debe11b67b4 100644
--- a/drivers/spi/mpc52xx_psc_spi.c
+++ b/drivers/spi/mpc52xx_psc_spi.c
@@ -15,13 +15,7 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/errno.h> 16#include <linux/errno.h>
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18
19#if defined(CONFIG_PPC_MERGE)
20#include <linux/of_platform.h> 18#include <linux/of_platform.h>
21#else
22#include <linux/platform_device.h>
23#endif
24
25#include <linux/workqueue.h> 19#include <linux/workqueue.h>
26#include <linux/completion.h> 20#include <linux/completion.h>
27#include <linux/io.h> 21#include <linux/io.h>
@@ -471,53 +465,6 @@ static int __exit mpc52xx_psc_spi_do_remove(struct device *dev)
471 return 0; 465 return 0;
472} 466}
473 467
474#if !defined(CONFIG_PPC_MERGE)
475static int __init mpc52xx_psc_spi_probe(struct platform_device *dev)
476{
477 switch(dev->id) {
478 case 1:
479 case 2:
480 case 3:
481 case 6:
482 return mpc52xx_psc_spi_do_probe(&dev->dev,
483 MPC52xx_PA(MPC52xx_PSCx_OFFSET(dev->id)),
484 MPC52xx_PSC_SIZE, platform_get_irq(dev, 0), dev->id);
485 default:
486 return -EINVAL;
487 }
488}
489
490static int __exit mpc52xx_psc_spi_remove(struct platform_device *dev)
491{
492 return mpc52xx_psc_spi_do_remove(&dev->dev);
493}
494
495/* work with hotplug and coldplug */
496MODULE_ALIAS("platform:mpc52xx-psc-spi");
497
498static struct platform_driver mpc52xx_psc_spi_platform_driver = {
499 .remove = __exit_p(mpc52xx_psc_spi_remove),
500 .driver = {
501 .name = "mpc52xx-psc-spi",
502 .owner = THIS_MODULE,
503 },
504};
505
506static int __init mpc52xx_psc_spi_init(void)
507{
508 return platform_driver_probe(&mpc52xx_psc_spi_platform_driver,
509 mpc52xx_psc_spi_probe);
510}
511module_init(mpc52xx_psc_spi_init);
512
513static void __exit mpc52xx_psc_spi_exit(void)
514{
515 platform_driver_unregister(&mpc52xx_psc_spi_platform_driver);
516}
517module_exit(mpc52xx_psc_spi_exit);
518
519#else /* defined(CONFIG_PPC_MERGE) */
520
521static int __init mpc52xx_psc_spi_of_probe(struct of_device *op, 468static int __init mpc52xx_psc_spi_of_probe(struct of_device *op,
522 const struct of_device_id *match) 469 const struct of_device_id *match)
523{ 470{
@@ -586,8 +533,6 @@ static void __exit mpc52xx_psc_spi_exit(void)
586} 533}
587module_exit(mpc52xx_psc_spi_exit); 534module_exit(mpc52xx_psc_spi_exit);
588 535
589#endif /* defined(CONFIG_PPC_MERGE) */
590
591MODULE_AUTHOR("Dragos Carp"); 536MODULE_AUTHOR("Dragos Carp");
592MODULE_DESCRIPTION("MPC52xx PSC SPI Driver"); 537MODULE_DESCRIPTION("MPC52xx PSC SPI Driver");
593MODULE_LICENSE("GPL"); 538MODULE_LICENSE("GPL");
diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c
index 9d2186fd74aa..454a2712e629 100644
--- a/drivers/spi/omap2_mcspi.c
+++ b/drivers/spi/omap2_mcspi.c
@@ -119,12 +119,14 @@ struct omap2_mcspi {
119 struct clk *fck; 119 struct clk *fck;
120 /* Virtual base address of the controller */ 120 /* Virtual base address of the controller */
121 void __iomem *base; 121 void __iomem *base;
122 unsigned long phys;
122 /* SPI1 has 4 channels, while SPI2 has 2 */ 123 /* SPI1 has 4 channels, while SPI2 has 2 */
123 struct omap2_mcspi_dma *dma_channels; 124 struct omap2_mcspi_dma *dma_channels;
124}; 125};
125 126
126struct omap2_mcspi_cs { 127struct omap2_mcspi_cs {
127 void __iomem *base; 128 void __iomem *base;
129 unsigned long phys;
128 int word_len; 130 int word_len;
129}; 131};
130 132
@@ -233,7 +235,7 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
233 c = count; 235 c = count;
234 word_len = cs->word_len; 236 word_len = cs->word_len;
235 237
236 base = (unsigned long) io_v2p(cs->base); 238 base = cs->phys;
237 tx_reg = base + OMAP2_MCSPI_TX0; 239 tx_reg = base + OMAP2_MCSPI_TX0;
238 rx_reg = base + OMAP2_MCSPI_RX0; 240 rx_reg = base + OMAP2_MCSPI_RX0;
239 rx = xfer->rx_buf; 241 rx = xfer->rx_buf;
@@ -633,6 +635,7 @@ static int omap2_mcspi_setup(struct spi_device *spi)
633 if (!cs) 635 if (!cs)
634 return -ENOMEM; 636 return -ENOMEM;
635 cs->base = mcspi->base + spi->chip_select * 0x14; 637 cs->base = mcspi->base + spi->chip_select * 0x14;
638 cs->phys = mcspi->phys + spi->chip_select * 0x14;
636 spi->controller_state = cs; 639 spi->controller_state = cs;
637 } 640 }
638 641
@@ -1005,7 +1008,13 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev)
1005 goto err1; 1008 goto err1;
1006 } 1009 }
1007 1010
1008 mcspi->base = (void __iomem *) io_p2v(r->start); 1011 mcspi->phys = r->start;
1012 mcspi->base = ioremap(r->start, r->end - r->start + 1);
1013 if (!mcspi->base) {
1014 dev_dbg(&pdev->dev, "can't ioremap MCSPI\n");
1015 status = -ENOMEM;
1016 goto err1aa;
1017 }
1009 1018
1010 INIT_WORK(&mcspi->work, omap2_mcspi_work); 1019 INIT_WORK(&mcspi->work, omap2_mcspi_work);
1011 1020
@@ -1055,6 +1064,8 @@ err3:
1055err2: 1064err2:
1056 clk_put(mcspi->ick); 1065 clk_put(mcspi->ick);
1057err1a: 1066err1a:
1067 iounmap(mcspi->base);
1068err1aa:
1058 release_mem_region(r->start, (r->end - r->start) + 1); 1069 release_mem_region(r->start, (r->end - r->start) + 1);
1059err1: 1070err1:
1060 spi_master_put(master); 1071 spi_master_put(master);
@@ -1067,6 +1078,7 @@ static int __exit omap2_mcspi_remove(struct platform_device *pdev)
1067 struct omap2_mcspi *mcspi; 1078 struct omap2_mcspi *mcspi;
1068 struct omap2_mcspi_dma *dma_channels; 1079 struct omap2_mcspi_dma *dma_channels;
1069 struct resource *r; 1080 struct resource *r;
1081 void __iomem *base;
1070 1082
1071 master = dev_get_drvdata(&pdev->dev); 1083 master = dev_get_drvdata(&pdev->dev);
1072 mcspi = spi_master_get_devdata(master); 1084 mcspi = spi_master_get_devdata(master);
@@ -1078,7 +1090,9 @@ static int __exit omap2_mcspi_remove(struct platform_device *pdev)
1078 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1090 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1079 release_mem_region(r->start, (r->end - r->start) + 1); 1091 release_mem_region(r->start, (r->end - r->start) + 1);
1080 1092
1093 base = mcspi->base;
1081 spi_unregister_master(master); 1094 spi_unregister_master(master);
1095 iounmap(base);
1082 kfree(dma_channels); 1096 kfree(dma_channels);
1083 1097
1084 return 0; 1098 return 0;
diff --git a/drivers/spi/omap_uwire.c b/drivers/spi/omap_uwire.c
index 5515eb97d7c5..bab6ff061e91 100644
--- a/drivers/spi/omap_uwire.c
+++ b/drivers/spi/omap_uwire.c
@@ -59,7 +59,6 @@
59 * and irqs should show there too... 59 * and irqs should show there too...
60 */ 60 */
61#define UWIRE_BASE_PHYS 0xFFFB3000 61#define UWIRE_BASE_PHYS 0xFFFB3000
62#define UWIRE_BASE ((void *__iomem)IO_ADDRESS(UWIRE_BASE_PHYS))
63 62
64/* uWire Registers: */ 63/* uWire Registers: */
65#define UWIRE_IO_SIZE 0x20 64#define UWIRE_IO_SIZE 0x20
@@ -103,16 +102,21 @@ struct uwire_state {
103}; 102};
104 103
105/* REVISIT compile time constant for idx_shift? */ 104/* REVISIT compile time constant for idx_shift? */
105/*
106 * Or, put it in a structure which is used throughout the driver;
107 * that avoids having to issue two loads for each bit of static data.
108 */
106static unsigned int uwire_idx_shift; 109static unsigned int uwire_idx_shift;
110static void __iomem *uwire_base;
107 111
108static inline void uwire_write_reg(int idx, u16 val) 112static inline void uwire_write_reg(int idx, u16 val)
109{ 113{
110 __raw_writew(val, UWIRE_BASE + (idx << uwire_idx_shift)); 114 __raw_writew(val, uwire_base + (idx << uwire_idx_shift));
111} 115}
112 116
113static inline u16 uwire_read_reg(int idx) 117static inline u16 uwire_read_reg(int idx)
114{ 118{
115 return __raw_readw(UWIRE_BASE + (idx << uwire_idx_shift)); 119 return __raw_readw(uwire_base + (idx << uwire_idx_shift));
116} 120}
117 121
118static inline void omap_uwire_configure_mode(u8 cs, unsigned long flags) 122static inline void omap_uwire_configure_mode(u8 cs, unsigned long flags)
@@ -492,6 +496,14 @@ static int __init uwire_probe(struct platform_device *pdev)
492 return -ENODEV; 496 return -ENODEV;
493 497
494 uwire = spi_master_get_devdata(master); 498 uwire = spi_master_get_devdata(master);
499
500 uwire_base = ioremap(UWIRE_BASE_PHYS, UWIRE_IO_SIZE);
501 if (!uwire_base) {
502 dev_dbg(&pdev->dev, "can't ioremap UWIRE\n");
503 spi_master_put(master);
504 return -ENOMEM;
505 }
506
495 dev_set_drvdata(&pdev->dev, uwire); 507 dev_set_drvdata(&pdev->dev, uwire);
496 508
497 uwire->ck = clk_get(&pdev->dev, "armxor_ck"); 509 uwire->ck = clk_get(&pdev->dev, "armxor_ck");
@@ -520,8 +532,10 @@ static int __init uwire_probe(struct platform_device *pdev)
520 uwire->bitbang.txrx_bufs = uwire_txrx; 532 uwire->bitbang.txrx_bufs = uwire_txrx;
521 533
522 status = spi_bitbang_start(&uwire->bitbang); 534 status = spi_bitbang_start(&uwire->bitbang);
523 if (status < 0) 535 if (status < 0) {
524 uwire_off(uwire); 536 uwire_off(uwire);
537 iounmap(uwire_base);
538 }
525 return status; 539 return status;
526} 540}
527 541
@@ -534,6 +548,7 @@ static int __exit uwire_remove(struct platform_device *pdev)
534 548
535 status = spi_bitbang_stop(&uwire->bitbang); 549 status = spi_bitbang_stop(&uwire->bitbang);
536 uwire_off(uwire); 550 uwire_off(uwire);
551 iounmap(uwire_base);
537 return status; 552 return status;
538} 553}
539 554
diff --git a/drivers/spi/orion_spi.c b/drivers/spi/orion_spi.c
index b872bfaf4bd2..014becb7d530 100644
--- a/drivers/spi/orion_spi.c
+++ b/drivers/spi/orion_spi.c
@@ -364,6 +364,11 @@ static int orion_spi_setup(struct spi_device *spi)
364 return -EINVAL; 364 return -EINVAL;
365 } 365 }
366 366
367 /* Fix ac timing if required. */
368 if (orion_spi->spi_info->enable_clock_fix)
369 orion_spi_setbits(orion_spi, ORION_SPI_IF_CONFIG_REG,
370 (1 << 14));
371
367 if (spi->bits_per_word == 0) 372 if (spi->bits_per_word == 0)
368 spi->bits_per_word = 8; 373 spi->bits_per_word = 8;
369 374
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
index d47d3636227f..dae87b1a4c6e 100644
--- a/drivers/spi/pxa2xx_spi.c
+++ b/drivers/spi/pxa2xx_spi.c
@@ -47,6 +47,10 @@ MODULE_ALIAS("platform:pxa2xx-spi");
47 47
48#define MAX_BUSES 3 48#define MAX_BUSES 3
49 49
50#define RX_THRESH_DFLT 8
51#define TX_THRESH_DFLT 8
52#define TIMOUT_DFLT 1000
53
50#define DMA_INT_MASK (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR) 54#define DMA_INT_MASK (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR)
51#define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK) 55#define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK)
52#define IS_DMA_ALIGNED(x) ((((u32)(x)) & 0x07) == 0) 56#define IS_DMA_ALIGNED(x) ((((u32)(x)) & 0x07) == 0)
@@ -1171,6 +1175,8 @@ static int setup(struct spi_device *spi)
1171 struct driver_data *drv_data = spi_master_get_devdata(spi->master); 1175 struct driver_data *drv_data = spi_master_get_devdata(spi->master);
1172 struct ssp_device *ssp = drv_data->ssp; 1176 struct ssp_device *ssp = drv_data->ssp;
1173 unsigned int clk_div; 1177 unsigned int clk_div;
1178 uint tx_thres = TX_THRESH_DFLT;
1179 uint rx_thres = RX_THRESH_DFLT;
1174 1180
1175 if (!spi->bits_per_word) 1181 if (!spi->bits_per_word)
1176 spi->bits_per_word = 8; 1182 spi->bits_per_word = 8;
@@ -1209,8 +1215,7 @@ static int setup(struct spi_device *spi)
1209 1215
1210 chip->cs_control = null_cs_control; 1216 chip->cs_control = null_cs_control;
1211 chip->enable_dma = 0; 1217 chip->enable_dma = 0;
1212 chip->timeout = 1000; 1218 chip->timeout = TIMOUT_DFLT;
1213 chip->threshold = SSCR1_RxTresh(1) | SSCR1_TxTresh(1);
1214 chip->dma_burst_size = drv_data->master_info->enable_dma ? 1219 chip->dma_burst_size = drv_data->master_info->enable_dma ?
1215 DCMD_BURST8 : 0; 1220 DCMD_BURST8 : 0;
1216 } 1221 }
@@ -1224,22 +1229,21 @@ static int setup(struct spi_device *spi)
1224 if (chip_info) { 1229 if (chip_info) {
1225 if (chip_info->cs_control) 1230 if (chip_info->cs_control)
1226 chip->cs_control = chip_info->cs_control; 1231 chip->cs_control = chip_info->cs_control;
1227 1232 if (chip_info->timeout)
1228 chip->timeout = chip_info->timeout; 1233 chip->timeout = chip_info->timeout;
1229 1234 if (chip_info->tx_threshold)
1230 chip->threshold = (SSCR1_RxTresh(chip_info->rx_threshold) & 1235 tx_thres = chip_info->tx_threshold;
1231 SSCR1_RFT) | 1236 if (chip_info->rx_threshold)
1232 (SSCR1_TxTresh(chip_info->tx_threshold) & 1237 rx_thres = chip_info->rx_threshold;
1233 SSCR1_TFT); 1238 chip->enable_dma = drv_data->master_info->enable_dma;
1234
1235 chip->enable_dma = chip_info->dma_burst_size != 0
1236 && drv_data->master_info->enable_dma;
1237 chip->dma_threshold = 0; 1239 chip->dma_threshold = 0;
1238
1239 if (chip_info->enable_loopback) 1240 if (chip_info->enable_loopback)
1240 chip->cr1 = SSCR1_LBM; 1241 chip->cr1 = SSCR1_LBM;
1241 } 1242 }
1242 1243
1244 chip->threshold = (SSCR1_RxTresh(rx_thres) & SSCR1_RFT) |
1245 (SSCR1_TxTresh(tx_thres) & SSCR1_TFT);
1246
1243 /* set dma burst and threshold outside of chip_info path so that if 1247 /* set dma burst and threshold outside of chip_info path so that if
1244 * chip_info goes away after setting chip->enable_dma, the 1248 * chip_info goes away after setting chip->enable_dma, the
1245 * burst and threshold can still respond to changes in bits_per_word */ 1249 * burst and threshold can still respond to changes in bits_per_word */
@@ -1268,17 +1272,19 @@ static int setup(struct spi_device *spi)
1268 1272
1269 /* NOTE: PXA25x_SSP _could_ use external clocking ... */ 1273 /* NOTE: PXA25x_SSP _could_ use external clocking ... */
1270 if (drv_data->ssp_type != PXA25x_SSP) 1274 if (drv_data->ssp_type != PXA25x_SSP)
1271 dev_dbg(&spi->dev, "%d bits/word, %ld Hz, mode %d\n", 1275 dev_dbg(&spi->dev, "%d bits/word, %ld Hz, mode %d, %s\n",
1272 spi->bits_per_word, 1276 spi->bits_per_word,
1273 clk_get_rate(ssp->clk) 1277 clk_get_rate(ssp->clk)
1274 / (1 + ((chip->cr0 & SSCR0_SCR) >> 8)), 1278 / (1 + ((chip->cr0 & SSCR0_SCR) >> 8)),
1275 spi->mode & 0x3); 1279 spi->mode & 0x3,
1280 chip->enable_dma ? "DMA" : "PIO");
1276 else 1281 else
1277 dev_dbg(&spi->dev, "%d bits/word, %ld Hz, mode %d\n", 1282 dev_dbg(&spi->dev, "%d bits/word, %ld Hz, mode %d, %s\n",
1278 spi->bits_per_word, 1283 spi->bits_per_word,
1279 clk_get_rate(ssp->clk) 1284 clk_get_rate(ssp->clk) / 2
1280 / (1 + ((chip->cr0 & SSCR0_SCR) >> 8)), 1285 / (1 + ((chip->cr0 & SSCR0_SCR) >> 8)),
1281 spi->mode & 0x3); 1286 spi->mode & 0x3,
1287 chip->enable_dma ? "DMA" : "PIO");
1282 1288
1283 if (spi->bits_per_word <= 8) { 1289 if (spi->bits_per_word <= 8) {
1284 chip->n_bytes = 1; 1290 chip->n_bytes = 1;
@@ -1407,9 +1413,9 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev)
1407 struct device *dev = &pdev->dev; 1413 struct device *dev = &pdev->dev;
1408 struct pxa2xx_spi_master *platform_info; 1414 struct pxa2xx_spi_master *platform_info;
1409 struct spi_master *master; 1415 struct spi_master *master;
1410 struct driver_data *drv_data = NULL; 1416 struct driver_data *drv_data;
1411 struct ssp_device *ssp; 1417 struct ssp_device *ssp;
1412 int status = 0; 1418 int status;
1413 1419
1414 platform_info = dev->platform_data; 1420 platform_info = dev->platform_data;
1415 1421
@@ -1422,7 +1428,7 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev)
1422 /* Allocate master with space for drv_data and null dma buffer */ 1428 /* Allocate master with space for drv_data and null dma buffer */
1423 master = spi_alloc_master(dev, sizeof(struct driver_data) + 16); 1429 master = spi_alloc_master(dev, sizeof(struct driver_data) + 16);
1424 if (!master) { 1430 if (!master) {
1425 dev_err(&pdev->dev, "can not alloc spi_master\n"); 1431 dev_err(&pdev->dev, "cannot alloc spi_master\n");
1426 ssp_free(ssp); 1432 ssp_free(ssp);
1427 return -ENOMEM; 1433 return -ENOMEM;
1428 } 1434 }
@@ -1458,7 +1464,7 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev)
1458 1464
1459 status = request_irq(ssp->irq, ssp_int, 0, dev->bus_id, drv_data); 1465 status = request_irq(ssp->irq, ssp_int, 0, dev->bus_id, drv_data);
1460 if (status < 0) { 1466 if (status < 0) {
1461 dev_err(&pdev->dev, "can not get IRQ\n"); 1467 dev_err(&pdev->dev, "cannot get IRQ %d\n", ssp->irq);
1462 goto out_error_master_alloc; 1468 goto out_error_master_alloc;
1463 } 1469 }
1464 1470
@@ -1498,7 +1504,9 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev)
1498 1504
1499 /* Load default SSP configuration */ 1505 /* Load default SSP configuration */
1500 write_SSCR0(0, drv_data->ioaddr); 1506 write_SSCR0(0, drv_data->ioaddr);
1501 write_SSCR1(SSCR1_RxTresh(4) | SSCR1_TxTresh(12), drv_data->ioaddr); 1507 write_SSCR1(SSCR1_RxTresh(RX_THRESH_DFLT) |
1508 SSCR1_TxTresh(TX_THRESH_DFLT),
1509 drv_data->ioaddr);
1502 write_SSCR0(SSCR0_SerClkDiv(2) 1510 write_SSCR0(SSCR0_SerClkDiv(2)
1503 | SSCR0_Motorola 1511 | SSCR0_Motorola
1504 | SSCR0_DataSize(8), 1512 | SSCR0_DataSize(8),
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 75e86865234c..3734dc9708e1 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -660,7 +660,7 @@ int spi_write_then_read(struct spi_device *spi,
660 660
661 int status; 661 int status;
662 struct spi_message message; 662 struct spi_message message;
663 struct spi_transfer x[2]; 663 struct spi_transfer x;
664 u8 *local_buf; 664 u8 *local_buf;
665 665
666 /* Use preallocated DMA-safe buffer. We can't avoid copying here, 666 /* Use preallocated DMA-safe buffer. We can't avoid copying here,
@@ -671,15 +671,9 @@ int spi_write_then_read(struct spi_device *spi,
671 return -EINVAL; 671 return -EINVAL;
672 672
673 spi_message_init(&message); 673 spi_message_init(&message);
674 memset(x, 0, sizeof x); 674 memset(&x, 0, sizeof x);
675 if (n_tx) { 675 x.len = n_tx + n_rx;
676 x[0].len = n_tx; 676 spi_message_add_tail(&x, &message);
677 spi_message_add_tail(&x[0], &message);
678 }
679 if (n_rx) {
680 x[1].len = n_rx;
681 spi_message_add_tail(&x[1], &message);
682 }
683 677
684 /* ... unless someone else is using the pre-allocated buffer */ 678 /* ... unless someone else is using the pre-allocated buffer */
685 if (!mutex_trylock(&lock)) { 679 if (!mutex_trylock(&lock)) {
@@ -690,15 +684,15 @@ int spi_write_then_read(struct spi_device *spi,
690 local_buf = buf; 684 local_buf = buf;
691 685
692 memcpy(local_buf, txbuf, n_tx); 686 memcpy(local_buf, txbuf, n_tx);
693 x[0].tx_buf = local_buf; 687 x.tx_buf = local_buf;
694 x[1].rx_buf = local_buf + n_tx; 688 x.rx_buf = local_buf;
695 689
696 /* do the i/o */ 690 /* do the i/o */
697 status = spi_sync(spi, &message); 691 status = spi_sync(spi, &message);
698 if (status == 0) 692 if (status == 0)
699 memcpy(rxbuf, x[1].rx_buf, n_rx); 693 memcpy(rxbuf, x.rx_buf + n_tx, n_rx);
700 694
701 if (x[0].tx_buf == buf) 695 if (x.tx_buf == buf)
702 mutex_unlock(&lock); 696 mutex_unlock(&lock);
703 else 697 else
704 kfree(local_buf); 698 kfree(local_buf);
@@ -744,5 +738,5 @@ err0:
744 * driver registration) _could_ be dynamically linked (modular) ... costs 738 * driver registration) _could_ be dynamically linked (modular) ... costs
745 * include needing to have boardinfo data structures be much more public. 739 * include needing to have boardinfo data structures be much more public.
746 */ 740 */
747subsys_initcall(spi_init); 741postcore_initcall(spi_init);
748 742
diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c
index 3eb414b84a9d..c252cbac00f1 100644
--- a/drivers/spi/spi_s3c24xx.c
+++ b/drivers/spi/spi_s3c24xx.c
@@ -247,6 +247,9 @@ static void s3c24xx_spi_initialsetup(struct s3c24xx_spi *hw)
247 writeb(0xff, hw->regs + S3C2410_SPPRE); 247 writeb(0xff, hw->regs + S3C2410_SPPRE);
248 writeb(SPPIN_DEFAULT, hw->regs + S3C2410_SPPIN); 248 writeb(SPPIN_DEFAULT, hw->regs + S3C2410_SPPIN);
249 writeb(SPCON_DEFAULT, hw->regs + S3C2410_SPCON); 249 writeb(SPCON_DEFAULT, hw->regs + S3C2410_SPCON);
250
251 if (hw->pdata && hw->pdata->gpio_setup)
252 hw->pdata->gpio_setup(hw->pdata, 1);
250} 253}
251 254
252static int __init s3c24xx_spi_probe(struct platform_device *pdev) 255static int __init s3c24xx_spi_probe(struct platform_device *pdev)
@@ -412,6 +415,9 @@ static int s3c24xx_spi_suspend(struct platform_device *pdev, pm_message_t msg)
412{ 415{
413 struct s3c24xx_spi *hw = platform_get_drvdata(pdev); 416 struct s3c24xx_spi *hw = platform_get_drvdata(pdev);
414 417
418 if (hw->pdata && hw->pdata->gpio_setup)
419 hw->pdata->gpio_setup(hw->pdata, 0);
420
415 clk_disable(hw->clk); 421 clk_disable(hw->clk);
416 return 0; 422 return 0;
417} 423}
diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c
index ec7aeb502d15..41b6530b8f25 100644
--- a/drivers/telephony/ixj.c
+++ b/drivers/telephony/ixj.c
@@ -42,8 +42,6 @@
42 ***************************************************************************/ 42 ***************************************************************************/
43 43
44/* 44/*
45 * $Log: ixj.c,v $
46 *
47 * Revision 4.8 2003/07/09 19:39:00 Daniele Bellucci 45 * Revision 4.8 2003/07/09 19:39:00 Daniele Bellucci
48 * Audit some copy_*_user and minor cleanup. 46 * Audit some copy_*_user and minor cleanup.
49 * 47 *
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index 95b3ec89c126..522185629624 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -344,7 +344,12 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
344 goto err1; 344 goto err1;
345 } 345 }
346 346
347 hcd->regs = (void __iomem *) (int) IO_ADDRESS(hcd->rsrc_start); 347 hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
348 if (!hcd->regs) {
349 dev_err(&pdev->dev, "can't ioremap OHCI HCD\n");
350 retval = -ENOMEM;
351 goto err2;
352 }
348 353
349 ohci = hcd_to_ohci(hcd); 354 ohci = hcd_to_ohci(hcd);
350 ohci_hcd_init(ohci); 355 ohci_hcd_init(ohci);
@@ -355,11 +360,11 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
355 irq = platform_get_irq(pdev, 0); 360 irq = platform_get_irq(pdev, 0);
356 if (irq < 0) { 361 if (irq < 0) {
357 retval = -ENXIO; 362 retval = -ENXIO;
358 goto err2; 363 goto err3;
359 } 364 }
360 retval = usb_add_hcd(hcd, irq, IRQF_DISABLED); 365 retval = usb_add_hcd(hcd, irq, IRQF_DISABLED);
361 if (retval) 366 if (retval)
362 goto err2; 367 goto err3;
363 368
364 host_initialized = 1; 369 host_initialized = 1;
365 370
@@ -367,6 +372,8 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
367 omap_ohci_clock_power(0); 372 omap_ohci_clock_power(0);
368 373
369 return 0; 374 return 0;
375err3:
376 iounmap(hcd->regs);
370err2: 377err2:
371 release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 378 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
372err1: 379err1:
@@ -401,6 +408,7 @@ usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
401 } 408 }
402 if (machine_is_omap_osk()) 409 if (machine_is_omap_osk())
403 omap_free_gpio(9); 410 omap_free_gpio(9);
411 iounmap(hcd->regs);
404 release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 412 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
405 usb_put_hcd(hcd); 413 usb_put_hcd(hcd);
406 clk_put(usb_dc_ck); 414 clk_put(usb_dc_ck);
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index f79c2040758b..0f13448c6f79 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -76,6 +76,14 @@ config FB_DDC
76 select I2C 76 select I2C
77 default n 77 default n
78 78
79config FB_BOOT_VESA_SUPPORT
80 bool
81 depends on FB
82 default n
83 ---help---
84 If true, at least one selected framebuffer driver can take advantage
85 of VESA video modes set at an early boot stage via the vga= parameter.
86
79config FB_CFB_FILLRECT 87config FB_CFB_FILLRECT
80 tristate 88 tristate
81 depends on FB 89 depends on FB
@@ -254,16 +262,24 @@ config FB_PM2
254 select FB_CFB_COPYAREA 262 select FB_CFB_COPYAREA
255 select FB_CFB_IMAGEBLIT 263 select FB_CFB_IMAGEBLIT
256 help 264 help
257 This is the frame buffer device driver for the Permedia2 AGP frame 265 This is the frame buffer device driver for cards based on
258 buffer card from ASK, aka `Graphic Blaster Exxtreme'. There is a 266 the 3D Labs Permedia, Permedia 2 and Permedia 2V chips.
259 product page at 267 The driver was tested on the following cards:
260 <http://www.ask.com.hk/product/Permedia%202/permedia2.htm>. 268 Diamond FireGL 1000 PRO AGP
269 ELSA Gloria Synergy PCI
270 Appian Jeronimo PRO (both heads) PCI
271 3DLabs Oxygen ACX aka EONtronics Picasso P2 PCI
272 Techsource Raptor GFX-8P (aka Sun PGX-32) on SPARC
273 ASK Graphic Blaster Exxtreme AGP
274
275 To compile this driver as a module, choose M here: the
276 module will be called pm2fb.
261 277
262config FB_PM2_FIFO_DISCONNECT 278config FB_PM2_FIFO_DISCONNECT
263 bool "enable FIFO disconnect feature" 279 bool "enable FIFO disconnect feature"
264 depends on FB_PM2 && PCI 280 depends on FB_PM2 && PCI
265 help 281 help
266 Support the Permedia2 FIFO disconnect feature (see CONFIG_FB_PM2). 282 Support the Permedia2 FIFO disconnect feature.
267 283
268config FB_ARMCLCD 284config FB_ARMCLCD
269 tristate "ARM PrimeCell PL110 support" 285 tristate "ARM PrimeCell PL110 support"
@@ -673,6 +689,7 @@ config FB_VESA
673 select FB_CFB_FILLRECT 689 select FB_CFB_FILLRECT
674 select FB_CFB_COPYAREA 690 select FB_CFB_COPYAREA
675 select FB_CFB_IMAGEBLIT 691 select FB_CFB_IMAGEBLIT
692 select FB_BOOT_VESA_SUPPORT
676 help 693 help
677 This is the frame buffer device driver for generic VESA 2.0 694 This is the frame buffer device driver for generic VESA 2.0
678 compliant graphic cards. The older VESA 1.2 cards are not supported. 695 compliant graphic cards. The older VESA 1.2 cards are not supported.
@@ -681,23 +698,14 @@ config FB_VESA
681 698
682config FB_EFI 699config FB_EFI
683 bool "EFI-based Framebuffer Support" 700 bool "EFI-based Framebuffer Support"
684 depends on (FB = y) && X86
685 select FB_CFB_FILLRECT
686 select FB_CFB_COPYAREA
687 select FB_CFB_IMAGEBLIT
688 help
689 This is the EFI frame buffer device driver. If the firmware on
690 your platform is UEFI2.0, select Y to add support for
691 Graphics Output Protocol for early console messages to appear.
692
693config FB_IMAC
694 bool "Intel-based Macintosh Framebuffer Support"
695 depends on (FB = y) && X86 && EFI 701 depends on (FB = y) && X86 && EFI
696 select FB_CFB_FILLRECT 702 select FB_CFB_FILLRECT
697 select FB_CFB_COPYAREA 703 select FB_CFB_COPYAREA
698 select FB_CFB_IMAGEBLIT 704 select FB_CFB_IMAGEBLIT
699 help 705 help
700 This is the frame buffer device driver for the Intel-based Macintosh 706 This is the EFI frame buffer device driver. If the firmware on
707 your platform is EFI 1.10 or UEFI 2.0, select Y to add support for
708 using the EFI framebuffer as your console.
701 709
702config FB_N411 710config FB_N411
703 tristate "N411 Apollo/Hecuba devkit support" 711 tristate "N411 Apollo/Hecuba devkit support"
@@ -1118,6 +1126,7 @@ config FB_INTEL
1118 select FB_CFB_FILLRECT 1126 select FB_CFB_FILLRECT
1119 select FB_CFB_COPYAREA 1127 select FB_CFB_COPYAREA
1120 select FB_CFB_IMAGEBLIT 1128 select FB_CFB_IMAGEBLIT
1129 select FB_BOOT_VESA_SUPPORT
1121 help 1130 help
1122 This driver supports the on-board graphics built in to the Intel 1131 This driver supports the on-board graphics built in to the Intel
1123 830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM chipsets. 1132 830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM chipsets.
@@ -1470,6 +1479,7 @@ config FB_SIS
1470 select FB_CFB_FILLRECT 1479 select FB_CFB_FILLRECT
1471 select FB_CFB_COPYAREA 1480 select FB_CFB_COPYAREA
1472 select FB_CFB_IMAGEBLIT 1481 select FB_CFB_IMAGEBLIT
1482 select FB_BOOT_VESA_SUPPORT
1473 help 1483 help
1474 This is the frame buffer device driver for the SiS 300, 315, 330 1484 This is the frame buffer device driver for the SiS 300, 315, 330
1475 and 340 series as well as XGI V3XT, V5, V8, Z7 graphics chipsets. 1485 and 340 series as well as XGI V3XT, V5, V8, Z7 graphics chipsets.
@@ -1492,6 +1502,24 @@ config FB_SIS_315
1492 (315/H/PRO, 55x, 650, 651, 740, 330, 661, 741, 760, 761) as well 1502 (315/H/PRO, 55x, 650, 651, 740, 330, 661, 741, 760, 761) as well
1493 as XGI V3XT, V5, V8 and Z7. 1503 as XGI V3XT, V5, V8 and Z7.
1494 1504
1505config FB_VIA
1506 tristate "VIA UniChrome (Pro) and Chrome9 display support"
1507 depends on FB && PCI
1508 select FB_CFB_FILLRECT
1509 select FB_CFB_COPYAREA
1510 select FB_CFB_IMAGEBLIT
1511 select FB_SOFT_CURSOR
1512 select I2C_ALGOBIT
1513 select I2C
1514 help
1515 This is the frame buffer device driver for Graphics chips of VIA
1516 UniChrome (Pro) Family (CLE266,PM800/CN400,P4M800CE/P4M800Pro/
1517 CN700/VN800,CX700/VX700,P4M890) and Chrome9 Family (K8M890,CN896
1518 /P4M900,VX800)
1519 Say Y if you have a VIA UniChrome graphics board.
1520
1521 To compile this driver as a module, choose M here: the
1522 module will be called viafb.
1495config FB_NEOMAGIC 1523config FB_NEOMAGIC
1496 tristate "NeoMagic display support" 1524 tristate "NeoMagic display support"
1497 depends on FB && PCI 1525 depends on FB && PCI
@@ -1521,25 +1549,25 @@ config FB_KYRO
1521 module will be called kyrofb. 1549 module will be called kyrofb.
1522 1550
1523config FB_3DFX 1551config FB_3DFX
1524 tristate "3Dfx Banshee/Voodoo3 display support" 1552 tristate "3Dfx Banshee/Voodoo3/Voodoo5 display support"
1525 depends on FB && PCI 1553 depends on FB && PCI
1526 select FB_CFB_IMAGEBLIT 1554 select FB_CFB_IMAGEBLIT
1527 select FB_CFB_FILLRECT 1555 select FB_CFB_FILLRECT
1528 select FB_CFB_COPYAREA 1556 select FB_CFB_COPYAREA
1529 help 1557 help
1530 This driver supports graphics boards with the 3Dfx Banshee/Voodoo3 1558 This driver supports graphics boards with the 3Dfx Banshee,
1531 chips. Say Y if you have such a graphics board. 1559 Voodoo3 or VSA-100 (aka Voodoo4/5) chips. Say Y if you have
1560 such a graphics board.
1532 1561
1533 To compile this driver as a module, choose M here: the 1562 To compile this driver as a module, choose M here: the
1534 module will be called tdfxfb. 1563 module will be called tdfxfb.
1535 1564
1536config FB_3DFX_ACCEL 1565config FB_3DFX_ACCEL
1537 bool "3Dfx Banshee/Voodoo3 Acceleration functions (EXPERIMENTAL)" 1566 bool "3Dfx Acceleration functions (EXPERIMENTAL)"
1538 depends on FB_3DFX && EXPERIMENTAL 1567 depends on FB_3DFX && EXPERIMENTAL
1539 ---help--- 1568 ---help---
1540 This will compile the 3Dfx Banshee/Voodoo3 frame buffer device 1569 This will compile the 3Dfx Banshee/Voodoo3/VSA-100 frame buffer
1541 with acceleration functions. 1570 device driver with acceleration functions.
1542
1543 1571
1544config FB_VOODOO1 1572config FB_VOODOO1
1545 tristate "3Dfx Voodoo Graphics (sst1) support" 1573 tristate "3Dfx Voodoo Graphics (sst1) support"
@@ -1604,17 +1632,16 @@ config FB_TRIDENT
1604 select FB_CFB_COPYAREA 1632 select FB_CFB_COPYAREA
1605 select FB_CFB_IMAGEBLIT 1633 select FB_CFB_IMAGEBLIT
1606 ---help--- 1634 ---help---
1607 This driver is supposed to support graphics boards with the 1635 This is the frame buffer device driver for Trident PCI/AGP chipsets.
1608 Trident CyberXXXX/Image/CyberBlade chips mostly found in laptops 1636 Supported chipset families are TGUI 9440/96XX, 3DImage, Blade3D
1637 and Blade XP.
1638 There are also integrated versions of these chips called CyberXXXX,
1639 CyberImage or CyberBlade. These chips are mostly found in laptops
1609 but also on some motherboards. For more information, read 1640 but also on some motherboards. For more information, read
1610 <file:Documentation/fb/tridentfb.txt> 1641 <file:Documentation/fb/tridentfb.txt>
1611 1642
1612 Cyberblade/i1 support will be removed soon, use the cyblafb driver
1613 instead.
1614
1615 Say Y if you have such a graphics board. 1643 Say Y if you have such a graphics board.
1616 1644
1617
1618 To compile this driver as a module, choose M here: the 1645 To compile this driver as a module, choose M here: the
1619 module will be called tridentfb. 1646 module will be called tridentfb.
1620 1647
@@ -1869,6 +1896,28 @@ config FB_SH_MOBILE_LCDC
1869 ---help--- 1896 ---help---
1870 Frame buffer driver for the on-chip SH-Mobile LCD controller. 1897 Frame buffer driver for the on-chip SH-Mobile LCD controller.
1871 1898
1899config FB_TMIO
1900 tristate "Toshiba Mobile IO FrameBuffer support"
1901 depends on FB && MFD_CORE
1902 select FB_CFB_FILLRECT
1903 select FB_CFB_COPYAREA
1904 select FB_CFB_IMAGEBLIT
1905 ---help---
1906 Frame buffer driver for the Toshiba Mobile IO integrated as found
1907 on the Sharp SL-6000 series
1908
1909 This driver is also available as a module ( = code which can be
1910 inserted and removed from the running kernel whenever you want). The
1911 module will be called tmiofb. If you want to compile it as a module,
1912 say M here and read <file:Documentation/kbuild/modules.txt>.
1913
1914 If unsure, say N.
1915
1916config FB_TMIO_ACCELL
1917 bool "tmiofb acceleration"
1918 depends on FB_TMIO
1919 default y
1920
1872config FB_S3C2410 1921config FB_S3C2410
1873 tristate "S3C2410 LCD framebuffer support" 1922 tristate "S3C2410 LCD framebuffer support"
1874 depends on FB && ARCH_S3C2410 1923 depends on FB && ARCH_S3C2410
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index ad0330bf9be3..248bddc8d0b0 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_FB_ATY) += aty/ macmodes.o
42obj-$(CONFIG_FB_ATY128) += aty/ macmodes.o 42obj-$(CONFIG_FB_ATY128) += aty/ macmodes.o
43obj-$(CONFIG_FB_RADEON) += aty/ 43obj-$(CONFIG_FB_RADEON) += aty/
44obj-$(CONFIG_FB_SIS) += sis/ 44obj-$(CONFIG_FB_SIS) += sis/
45obj-$(CONFIG_FB_VIA) += via/
45obj-$(CONFIG_FB_KYRO) += kyro/ 46obj-$(CONFIG_FB_KYRO) += kyro/
46obj-$(CONFIG_FB_SAVAGE) += savage/ 47obj-$(CONFIG_FB_SAVAGE) += savage/
47obj-$(CONFIG_FB_GEODE) += geode/ 48obj-$(CONFIG_FB_GEODE) += geode/
@@ -97,6 +98,7 @@ obj-$(CONFIG_FB_CIRRUS) += cirrusfb.o
97obj-$(CONFIG_FB_ASILIANT) += asiliantfb.o 98obj-$(CONFIG_FB_ASILIANT) += asiliantfb.o
98obj-$(CONFIG_FB_PXA) += pxafb.o 99obj-$(CONFIG_FB_PXA) += pxafb.o
99obj-$(CONFIG_FB_W100) += w100fb.o 100obj-$(CONFIG_FB_W100) += w100fb.o
101obj-$(CONFIG_FB_TMIO) += tmiofb.o
100obj-$(CONFIG_FB_AU1100) += au1100fb.o 102obj-$(CONFIG_FB_AU1100) += au1100fb.o
101obj-$(CONFIG_FB_AU1200) += au1200fb.o 103obj-$(CONFIG_FB_AU1200) += au1200fb.o
102obj-$(CONFIG_FB_PMAG_AA) += pmag-aa-fb.o 104obj-$(CONFIG_FB_PMAG_AA) += pmag-aa-fb.o
@@ -124,7 +126,6 @@ obj-$(CONFIG_FB_CARMINE) += carminefb.o
124# Platform or fallback drivers go here 126# Platform or fallback drivers go here
125obj-$(CONFIG_FB_UVESA) += uvesafb.o 127obj-$(CONFIG_FB_UVESA) += uvesafb.o
126obj-$(CONFIG_FB_VESA) += vesafb.o 128obj-$(CONFIG_FB_VESA) += vesafb.o
127obj-$(CONFIG_FB_IMAC) += imacfb.o
128obj-$(CONFIG_FB_EFI) += efifb.o 129obj-$(CONFIG_FB_EFI) += efifb.o
129obj-$(CONFIG_FB_VGA16) += vga16fb.o 130obj-$(CONFIG_FB_VGA16) += vga16fb.o
130obj-$(CONFIG_FB_OF) += offb.o 131obj-$(CONFIG_FB_OF) += offb.o
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index d38fd5217422..f8d0a57a07cb 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -372,6 +372,13 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var,
372 var->transp.offset = var->transp.length = 0; 372 var->transp.offset = var->transp.length = 0;
373 var->xoffset = var->yoffset = 0; 373 var->xoffset = var->yoffset = 0;
374 374
375 if (info->fix.smem_len) {
376 unsigned int smem_len = (var->xres_virtual * var->yres_virtual
377 * ((var->bits_per_pixel + 7) / 8));
378 if (smem_len > info->fix.smem_len)
379 return -EINVAL;
380 }
381
375 /* Saturate vertical and horizontal timings at maximum values */ 382 /* Saturate vertical and horizontal timings at maximum values */
376 var->vsync_len = min_t(u32, var->vsync_len, 383 var->vsync_len = min_t(u32, var->vsync_len,
377 (ATMEL_LCDC_VPW >> ATMEL_LCDC_VPW_OFFSET) + 1); 384 (ATMEL_LCDC_VPW >> ATMEL_LCDC_VPW_OFFSET) + 1);
diff --git a/drivers/video/aty/radeon_accel.c b/drivers/video/aty/radeon_accel.c
index aa95f8350242..8718f7349d6b 100644
--- a/drivers/video/aty/radeon_accel.c
+++ b/drivers/video/aty/radeon_accel.c
@@ -5,61 +5,61 @@
5 * --dte 5 * --dte
6 */ 6 */
7 7
8static void radeon_fixup_offset(struct radeonfb_info *rinfo) 8#define FLUSH_CACHE_WORKAROUND 1
9
10void radeon_fifo_update_and_wait(struct radeonfb_info *rinfo, int entries)
9{ 11{
10 u32 local_base; 12 int i;
11
12 /* *** Ugly workaround *** */
13 /*
14 * On some platforms, the video memory is mapped at 0 in radeon chip space
15 * (like PPCs) by the firmware. X will always move it up so that it's seen
16 * by the chip to be at the same address as the PCI BAR.
17 * That means that when switching back from X, there is a mismatch between
18 * the offsets programmed into the engine. This means that potentially,
19 * accel operations done before radeonfb has a chance to re-init the engine
20 * will have incorrect offsets, and potentially trash system memory !
21 *
22 * The correct fix is for fbcon to never call any accel op before the engine
23 * has properly been re-initialized (by a call to set_var), but this is a
24 * complex fix. This workaround in the meantime, called before every accel
25 * operation, makes sure the offsets are in sync.
26 */
27 13
28 radeon_fifo_wait (1); 14 for (i=0; i<2000000; i++) {
29 local_base = INREG(MC_FB_LOCATION) << 16; 15 rinfo->fifo_free = INREG(RBBM_STATUS) & 0x7f;
30 if (local_base == rinfo->fb_local_base) 16 if (rinfo->fifo_free >= entries)
31 return; 17 return;
18 udelay(10);
19 }
20 printk(KERN_ERR "radeonfb: FIFO Timeout !\n");
21 /* XXX Todo: attempt to reset the engine */
22}
32 23
33 rinfo->fb_local_base = local_base; 24static inline void radeon_fifo_wait(struct radeonfb_info *rinfo, int entries)
25{
26 if (entries <= rinfo->fifo_free)
27 rinfo->fifo_free -= entries;
28 else
29 radeon_fifo_update_and_wait(rinfo, entries);
30}
34 31
35 radeon_fifo_wait (3); 32static inline void radeonfb_set_creg(struct radeonfb_info *rinfo, u32 reg,
36 OUTREG(DEFAULT_PITCH_OFFSET, (rinfo->pitch << 0x16) | 33 u32 *cache, u32 new_val)
37 (rinfo->fb_local_base >> 10)); 34{
38 OUTREG(DST_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10)); 35 if (new_val == *cache)
39 OUTREG(SRC_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10)); 36 return;
37 *cache = new_val;
38 radeon_fifo_wait(rinfo, 1);
39 OUTREG(reg, new_val);
40} 40}
41 41
42static void radeonfb_prim_fillrect(struct radeonfb_info *rinfo, 42static void radeonfb_prim_fillrect(struct radeonfb_info *rinfo,
43 const struct fb_fillrect *region) 43 const struct fb_fillrect *region)
44{ 44{
45 radeon_fifo_wait(4); 45 radeonfb_set_creg(rinfo, DP_GUI_MASTER_CNTL, &rinfo->dp_gui_mc_cache,
46 46 rinfo->dp_gui_mc_base | GMC_BRUSH_SOLID_COLOR | ROP3_P);
47 OUTREG(DP_GUI_MASTER_CNTL, 47 radeonfb_set_creg(rinfo, DP_CNTL, &rinfo->dp_cntl_cache,
48 rinfo->dp_gui_master_cntl /* contains, like GMC_DST_32BPP */ 48 DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM);
49 | GMC_BRUSH_SOLID_COLOR 49 radeonfb_set_creg(rinfo, DP_BRUSH_FRGD_CLR, &rinfo->dp_brush_fg_cache,
50 | ROP3_P); 50 region->color);
51 if (radeon_get_dstbpp(rinfo->depth) != DST_8BPP) 51
52 OUTREG(DP_BRUSH_FRGD_CLR, rinfo->pseudo_palette[region->color]); 52 /* Ensure the dst cache is flushed and the engine idle before
53 else 53 * issuing the operation.
54 OUTREG(DP_BRUSH_FRGD_CLR, region->color); 54 *
55 OUTREG(DP_WRITE_MSK, 0xffffffff); 55 * This works around engine lockups on some cards
56 OUTREG(DP_CNTL, (DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM)); 56 */
57 57#if FLUSH_CACHE_WORKAROUND
58 radeon_fifo_wait(2); 58 radeon_fifo_wait(rinfo, 2);
59 OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL); 59 OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL);
60 OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE)); 60 OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE));
61 61#endif
62 radeon_fifo_wait(2); 62 radeon_fifo_wait(rinfo, 2);
63 OUTREG(DST_Y_X, (region->dy << 16) | region->dx); 63 OUTREG(DST_Y_X, (region->dy << 16) | region->dx);
64 OUTREG(DST_WIDTH_HEIGHT, (region->width << 16) | region->height); 64 OUTREG(DST_WIDTH_HEIGHT, (region->width << 16) | region->height);
65} 65}
@@ -70,15 +70,14 @@ void radeonfb_fillrect(struct fb_info *info, const struct fb_fillrect *region)
70 struct fb_fillrect modded; 70 struct fb_fillrect modded;
71 int vxres, vyres; 71 int vxres, vyres;
72 72
73 if (info->state != FBINFO_STATE_RUNNING) 73 WARN_ON(rinfo->gfx_mode);
74 if (info->state != FBINFO_STATE_RUNNING || rinfo->gfx_mode)
74 return; 75 return;
75 if (info->flags & FBINFO_HWACCEL_DISABLED) { 76 if (info->flags & FBINFO_HWACCEL_DISABLED) {
76 cfb_fillrect(info, region); 77 cfb_fillrect(info, region);
77 return; 78 return;
78 } 79 }
79 80
80 radeon_fixup_offset(rinfo);
81
82 vxres = info->var.xres_virtual; 81 vxres = info->var.xres_virtual;
83 vyres = info->var.yres_virtual; 82 vyres = info->var.yres_virtual;
84 83
@@ -91,6 +90,10 @@ void radeonfb_fillrect(struct fb_info *info, const struct fb_fillrect *region)
91 if(modded.dx + modded.width > vxres) modded.width = vxres - modded.dx; 90 if(modded.dx + modded.width > vxres) modded.width = vxres - modded.dx;
92 if(modded.dy + modded.height > vyres) modded.height = vyres - modded.dy; 91 if(modded.dy + modded.height > vyres) modded.height = vyres - modded.dy;
93 92
93 if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
94 info->fix.visual == FB_VISUAL_DIRECTCOLOR )
95 modded.color = ((u32 *) (info->pseudo_palette))[region->color];
96
94 radeonfb_prim_fillrect(rinfo, &modded); 97 radeonfb_prim_fillrect(rinfo, &modded);
95} 98}
96 99
@@ -109,22 +112,22 @@ static void radeonfb_prim_copyarea(struct radeonfb_info *rinfo,
109 if ( xdir < 0 ) { sx += w-1; dx += w-1; } 112 if ( xdir < 0 ) { sx += w-1; dx += w-1; }
110 if ( ydir < 0 ) { sy += h-1; dy += h-1; } 113 if ( ydir < 0 ) { sy += h-1; dy += h-1; }
111 114
112 radeon_fifo_wait(3); 115 radeonfb_set_creg(rinfo, DP_GUI_MASTER_CNTL, &rinfo->dp_gui_mc_cache,
113 OUTREG(DP_GUI_MASTER_CNTL, 116 rinfo->dp_gui_mc_base |
114 rinfo->dp_gui_master_cntl /* i.e. GMC_DST_32BPP */ 117 GMC_BRUSH_NONE |
115 | GMC_BRUSH_NONE 118 GMC_SRC_DATATYPE_COLOR |
116 | GMC_SRC_DSTCOLOR 119 ROP3_S |
117 | ROP3_S 120 DP_SRC_SOURCE_MEMORY);
118 | DP_SRC_SOURCE_MEMORY ); 121 radeonfb_set_creg(rinfo, DP_CNTL, &rinfo->dp_cntl_cache,
119 OUTREG(DP_WRITE_MSK, 0xffffffff); 122 (xdir>=0 ? DST_X_LEFT_TO_RIGHT : 0) |
120 OUTREG(DP_CNTL, (xdir>=0 ? DST_X_LEFT_TO_RIGHT : 0) 123 (ydir>=0 ? DST_Y_TOP_TO_BOTTOM : 0));
121 | (ydir>=0 ? DST_Y_TOP_TO_BOTTOM : 0)); 124
122 125#if FLUSH_CACHE_WORKAROUND
123 radeon_fifo_wait(2); 126 radeon_fifo_wait(rinfo, 2);
124 OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL); 127 OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL);
125 OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE)); 128 OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE));
126 129#endif
127 radeon_fifo_wait(3); 130 radeon_fifo_wait(rinfo, 3);
128 OUTREG(SRC_Y_X, (sy << 16) | sx); 131 OUTREG(SRC_Y_X, (sy << 16) | sx);
129 OUTREG(DST_Y_X, (dy << 16) | dx); 132 OUTREG(DST_Y_X, (dy << 16) | dx);
130 OUTREG(DST_HEIGHT_WIDTH, (h << 16) | w); 133 OUTREG(DST_HEIGHT_WIDTH, (h << 16) | w);
@@ -143,15 +146,14 @@ void radeonfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
143 modded.width = area->width; 146 modded.width = area->width;
144 modded.height = area->height; 147 modded.height = area->height;
145 148
146 if (info->state != FBINFO_STATE_RUNNING) 149 WARN_ON(rinfo->gfx_mode);
150 if (info->state != FBINFO_STATE_RUNNING || rinfo->gfx_mode)
147 return; 151 return;
148 if (info->flags & FBINFO_HWACCEL_DISABLED) { 152 if (info->flags & FBINFO_HWACCEL_DISABLED) {
149 cfb_copyarea(info, area); 153 cfb_copyarea(info, area);
150 return; 154 return;
151 } 155 }
152 156
153 radeon_fixup_offset(rinfo);
154
155 vxres = info->var.xres_virtual; 157 vxres = info->var.xres_virtual;
156 vyres = info->var.yres_virtual; 158 vyres = info->var.yres_virtual;
157 159
@@ -168,13 +170,112 @@ void radeonfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
168 radeonfb_prim_copyarea(rinfo, &modded); 170 radeonfb_prim_copyarea(rinfo, &modded);
169} 171}
170 172
173static void radeonfb_prim_imageblit(struct radeonfb_info *rinfo,
174 const struct fb_image *image,
175 u32 fg, u32 bg)
176{
177 unsigned int src_bytes, dwords;
178 u32 *bits;
179
180 radeonfb_set_creg(rinfo, DP_GUI_MASTER_CNTL, &rinfo->dp_gui_mc_cache,
181 rinfo->dp_gui_mc_base |
182 GMC_BRUSH_NONE |
183 GMC_SRC_DATATYPE_MONO_FG_BG |
184 ROP3_S |
185 GMC_BYTE_ORDER_MSB_TO_LSB |
186 DP_SRC_SOURCE_HOST_DATA);
187 radeonfb_set_creg(rinfo, DP_CNTL, &rinfo->dp_cntl_cache,
188 DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM);
189 radeonfb_set_creg(rinfo, DP_SRC_FRGD_CLR, &rinfo->dp_src_fg_cache, fg);
190 radeonfb_set_creg(rinfo, DP_SRC_BKGD_CLR, &rinfo->dp_src_bg_cache, bg);
191
192 radeon_fifo_wait(rinfo, 1);
193 OUTREG(DST_Y_X, (image->dy << 16) | image->dx);
194
195 /* Ensure the dst cache is flushed and the engine idle before
196 * issuing the operation.
197 *
198 * This works around engine lockups on some cards
199 */
200#if FLUSH_CACHE_WORKAROUND
201 radeon_fifo_wait(rinfo, 2);
202 OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL);
203 OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE));
204#endif
205
206 /* X here pads width to a multiple of 32 and uses the clipper to
207 * adjust the result. Is that really necessary ? Things seem to
208 * work ok for me without that and the doco doesn't seem to imply
209 * there is such a restriction.
210 */
211 OUTREG(DST_WIDTH_HEIGHT, (image->width << 16) | image->height);
212
213 src_bytes = (((image->width * image->depth) + 7) / 8) * image->height;
214 dwords = (src_bytes + 3) / 4;
215 bits = (u32*)(image->data);
216
217 while(dwords >= 8) {
218 radeon_fifo_wait(rinfo, 8);
219#if BITS_PER_LONG == 64
220 __raw_writeq(*((u64 *)(bits)), rinfo->mmio_base + HOST_DATA0);
221 __raw_writeq(*((u64 *)(bits+2)), rinfo->mmio_base + HOST_DATA2);
222 __raw_writeq(*((u64 *)(bits+4)), rinfo->mmio_base + HOST_DATA4);
223 __raw_writeq(*((u64 *)(bits+6)), rinfo->mmio_base + HOST_DATA6);
224 bits += 8;
225#else
226 __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA0);
227 __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA1);
228 __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA2);
229 __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA3);
230 __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA4);
231 __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA5);
232 __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA6);
233 __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA7);
234#endif
235 dwords -= 8;
236 }
237 while(dwords--) {
238 radeon_fifo_wait(rinfo, 1);
239 __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA0);
240 }
241}
242
171void radeonfb_imageblit(struct fb_info *info, const struct fb_image *image) 243void radeonfb_imageblit(struct fb_info *info, const struct fb_image *image)
172{ 244{
173 struct radeonfb_info *rinfo = info->par; 245 struct radeonfb_info *rinfo = info->par;
246 u32 fg, bg;
174 247
175 if (info->state != FBINFO_STATE_RUNNING) 248 WARN_ON(rinfo->gfx_mode);
249 if (info->state != FBINFO_STATE_RUNNING || rinfo->gfx_mode)
250 return;
251
252 if (!image->width || !image->height)
176 return; 253 return;
177 radeon_engine_idle(); 254
255 /* We only do 1 bpp color expansion for now */
256 if (info->flags & FBINFO_HWACCEL_DISABLED || image->depth != 1)
257 goto fallback;
258
259 /* Fallback if running out of the screen. We may do clipping
260 * in the future */
261 if ((image->dx + image->width) > info->var.xres_virtual ||
262 (image->dy + image->height) > info->var.yres_virtual)
263 goto fallback;
264
265 if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
266 info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
267 fg = ((u32*)(info->pseudo_palette))[image->fg_color];
268 bg = ((u32*)(info->pseudo_palette))[image->bg_color];
269 } else {
270 fg = image->fg_color;
271 bg = image->bg_color;
272 }
273
274 radeonfb_prim_imageblit(rinfo, image, fg, bg);
275 return;
276
277 fallback:
278 radeon_engine_idle(rinfo);
178 279
179 cfb_imageblit(info, image); 280 cfb_imageblit(info, image);
180} 281}
@@ -185,7 +286,8 @@ int radeonfb_sync(struct fb_info *info)
185 286
186 if (info->state != FBINFO_STATE_RUNNING) 287 if (info->state != FBINFO_STATE_RUNNING)
187 return 0; 288 return 0;
188 radeon_engine_idle(); 289
290 radeon_engine_idle(rinfo);
189 291
190 return 0; 292 return 0;
191} 293}
@@ -211,9 +313,7 @@ void radeonfb_engine_reset(struct radeonfb_info *rinfo)
211 host_path_cntl = INREG(HOST_PATH_CNTL); 313 host_path_cntl = INREG(HOST_PATH_CNTL);
212 rbbm_soft_reset = INREG(RBBM_SOFT_RESET); 314 rbbm_soft_reset = INREG(RBBM_SOFT_RESET);
213 315
214 if (rinfo->family == CHIP_FAMILY_R300 || 316 if (IS_R300_VARIANT(rinfo)) {
215 rinfo->family == CHIP_FAMILY_R350 ||
216 rinfo->family == CHIP_FAMILY_RV350) {
217 u32 tmp; 317 u32 tmp;
218 318
219 OUTREG(RBBM_SOFT_RESET, (rbbm_soft_reset | 319 OUTREG(RBBM_SOFT_RESET, (rbbm_soft_reset |
@@ -249,9 +349,7 @@ void radeonfb_engine_reset(struct radeonfb_info *rinfo)
249 INREG(HOST_PATH_CNTL); 349 INREG(HOST_PATH_CNTL);
250 OUTREG(HOST_PATH_CNTL, host_path_cntl); 350 OUTREG(HOST_PATH_CNTL, host_path_cntl);
251 351
252 if (rinfo->family != CHIP_FAMILY_R300 && 352 if (!IS_R300_VARIANT(rinfo))
253 rinfo->family != CHIP_FAMILY_R350 &&
254 rinfo->family != CHIP_FAMILY_RV350)
255 OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset); 353 OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset);
256 354
257 OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index); 355 OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index);
@@ -265,15 +363,24 @@ void radeonfb_engine_init (struct radeonfb_info *rinfo)
265 /* disable 3D engine */ 363 /* disable 3D engine */
266 OUTREG(RB3D_CNTL, 0); 364 OUTREG(RB3D_CNTL, 0);
267 365
366 rinfo->fifo_free = 0;
268 radeonfb_engine_reset(rinfo); 367 radeonfb_engine_reset(rinfo);
269 368
270 radeon_fifo_wait (1); 369 radeon_fifo_wait(rinfo, 1);
271 if ((rinfo->family != CHIP_FAMILY_R300) && 370 if (IS_R300_VARIANT(rinfo)) {
272 (rinfo->family != CHIP_FAMILY_R350) && 371 OUTREG(RB2D_DSTCACHE_MODE, INREG(RB2D_DSTCACHE_MODE) |
273 (rinfo->family != CHIP_FAMILY_RV350)) 372 RB2D_DC_AUTOFLUSH_ENABLE |
373 RB2D_DC_DC_DISABLE_IGNORE_PE);
374 } else {
375 /* This needs to be double checked with ATI. Latest X driver
376 * completely "forgets" to set this register on < r3xx, and
377 * we used to just write 0 there... I'll keep the 0 and update
378 * that when we have sorted things out on X side.
379 */
274 OUTREG(RB2D_DSTCACHE_MODE, 0); 380 OUTREG(RB2D_DSTCACHE_MODE, 0);
381 }
275 382
276 radeon_fifo_wait (3); 383 radeon_fifo_wait(rinfo, 3);
277 /* We re-read MC_FB_LOCATION from card as it can have been 384 /* We re-read MC_FB_LOCATION from card as it can have been
278 * modified by XFree drivers (ouch !) 385 * modified by XFree drivers (ouch !)
279 */ 386 */
@@ -284,41 +391,57 @@ void radeonfb_engine_init (struct radeonfb_info *rinfo)
284 OUTREG(DST_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10)); 391 OUTREG(DST_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10));
285 OUTREG(SRC_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10)); 392 OUTREG(SRC_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10));
286 393
287 radeon_fifo_wait (1); 394 radeon_fifo_wait(rinfo, 1);
288#if defined(__BIG_ENDIAN) 395#ifdef __BIG_ENDIAN
289 OUTREGP(DP_DATATYPE, HOST_BIG_ENDIAN_EN, ~HOST_BIG_ENDIAN_EN); 396 OUTREGP(DP_DATATYPE, HOST_BIG_ENDIAN_EN, ~HOST_BIG_ENDIAN_EN);
290#else 397#else
291 OUTREGP(DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN); 398 OUTREGP(DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN);
292#endif 399#endif
293 radeon_fifo_wait (2); 400 radeon_fifo_wait(rinfo, 2);
294 OUTREG(DEFAULT_SC_TOP_LEFT, 0); 401 OUTREG(DEFAULT_SC_TOP_LEFT, 0);
295 OUTREG(DEFAULT_SC_BOTTOM_RIGHT, (DEFAULT_SC_RIGHT_MAX | 402 OUTREG(DEFAULT_SC_BOTTOM_RIGHT, (DEFAULT_SC_RIGHT_MAX |
296 DEFAULT_SC_BOTTOM_MAX)); 403 DEFAULT_SC_BOTTOM_MAX));
297 404
405 /* set default DP_GUI_MASTER_CNTL */
298 temp = radeon_get_dstbpp(rinfo->depth); 406 temp = radeon_get_dstbpp(rinfo->depth);
299 rinfo->dp_gui_master_cntl = ((temp << 8) | GMC_CLR_CMP_CNTL_DIS); 407 rinfo->dp_gui_mc_base = ((temp << 8) | GMC_CLR_CMP_CNTL_DIS);
300 408
301 radeon_fifo_wait (1); 409 rinfo->dp_gui_mc_cache = rinfo->dp_gui_mc_base |
302 OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl | 410 GMC_BRUSH_SOLID_COLOR |
303 GMC_BRUSH_SOLID_COLOR | 411 GMC_SRC_DATATYPE_COLOR;
304 GMC_SRC_DATATYPE_COLOR)); 412 radeon_fifo_wait(rinfo, 1);
413 OUTREG(DP_GUI_MASTER_CNTL, rinfo->dp_gui_mc_cache);
305 414
306 radeon_fifo_wait (7);
307 415
308 /* clear line drawing regs */ 416 /* clear line drawing regs */
417 radeon_fifo_wait(rinfo, 2);
309 OUTREG(DST_LINE_START, 0); 418 OUTREG(DST_LINE_START, 0);
310 OUTREG(DST_LINE_END, 0); 419 OUTREG(DST_LINE_END, 0);
311 420
312 /* set brush color regs */ 421 /* set brush and source color regs */
313 OUTREG(DP_BRUSH_FRGD_CLR, 0xffffffff); 422 rinfo->dp_brush_fg_cache = 0xffffffff;
314 OUTREG(DP_BRUSH_BKGD_CLR, 0x00000000); 423 rinfo->dp_brush_bg_cache = 0x00000000;
315 424 rinfo->dp_src_fg_cache = 0xffffffff;
316 /* set source color regs */ 425 rinfo->dp_src_bg_cache = 0x00000000;
317 OUTREG(DP_SRC_FRGD_CLR, 0xffffffff); 426 radeon_fifo_wait(rinfo, 4);
318 OUTREG(DP_SRC_BKGD_CLR, 0x00000000); 427 OUTREG(DP_BRUSH_FRGD_CLR, rinfo->dp_brush_fg_cache);
428 OUTREG(DP_BRUSH_BKGD_CLR, rinfo->dp_brush_bg_cache);
429 OUTREG(DP_SRC_FRGD_CLR, rinfo->dp_src_fg_cache);
430 OUTREG(DP_SRC_BKGD_CLR, rinfo->dp_src_bg_cache);
431
432 /* Default direction */
433 rinfo->dp_cntl_cache = DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM;
434 radeon_fifo_wait(rinfo, 1);
435 OUTREG(DP_CNTL, rinfo->dp_cntl_cache);
319 436
320 /* default write mask */ 437 /* default write mask */
438 radeon_fifo_wait(rinfo, 1);
321 OUTREG(DP_WRITE_MSK, 0xffffffff); 439 OUTREG(DP_WRITE_MSK, 0xffffffff);
322 440
323 radeon_engine_idle (); 441 /* Default to no swapping of host data */
442 radeon_fifo_wait(rinfo, 1);
443 OUTREG(RBBM_GUICNTL, RBBM_GUICNTL_HOST_DATA_SWAP_NONE);
444
445 /* Make sure it's settled */
446 radeon_engine_idle(rinfo);
324} 447}
diff --git a/drivers/video/aty/radeon_backlight.c b/drivers/video/aty/radeon_backlight.c
index 1a056adb61c8..f343ba83f0ae 100644
--- a/drivers/video/aty/radeon_backlight.c
+++ b/drivers/video/aty/radeon_backlight.c
@@ -66,7 +66,7 @@ static int radeon_bl_update_status(struct backlight_device *bd)
66 level = bd->props.brightness; 66 level = bd->props.brightness;
67 67
68 del_timer_sync(&rinfo->lvds_timer); 68 del_timer_sync(&rinfo->lvds_timer);
69 radeon_engine_idle(); 69 radeon_engine_idle(rinfo);
70 70
71 lvds_gen_cntl = INREG(LVDS_GEN_CNTL); 71 lvds_gen_cntl = INREG(LVDS_GEN_CNTL);
72 if (level > 0) { 72 if (level > 0) {
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index 652273e9f5f9..9a5821c65ebf 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -852,7 +852,6 @@ static int radeonfb_pan_display (struct fb_var_screeninfo *var,
852 if (rinfo->asleep) 852 if (rinfo->asleep)
853 return 0; 853 return 0;
854 854
855 radeon_fifo_wait(2);
856 OUTREG(CRTC_OFFSET, ((var->yoffset * var->xres_virtual + var->xoffset) 855 OUTREG(CRTC_OFFSET, ((var->yoffset * var->xres_virtual + var->xoffset)
857 * var->bits_per_pixel / 8) & ~7); 856 * var->bits_per_pixel / 8) & ~7);
858 return 0; 857 return 0;
@@ -882,7 +881,6 @@ static int radeonfb_ioctl (struct fb_info *info, unsigned int cmd,
882 if (rc) 881 if (rc)
883 return rc; 882 return rc;
884 883
885 radeon_fifo_wait(2);
886 if (value & 0x01) { 884 if (value & 0x01) {
887 tmp = INREG(LVDS_GEN_CNTL); 885 tmp = INREG(LVDS_GEN_CNTL);
888 886
@@ -940,7 +938,7 @@ int radeon_screen_blank(struct radeonfb_info *rinfo, int blank, int mode_switch)
940 if (rinfo->lock_blank) 938 if (rinfo->lock_blank)
941 return 0; 939 return 0;
942 940
943 radeon_engine_idle(); 941 radeon_engine_idle(rinfo);
944 942
945 val = INREG(CRTC_EXT_CNTL); 943 val = INREG(CRTC_EXT_CNTL);
946 val &= ~(CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS | 944 val &= ~(CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS |
@@ -1048,7 +1046,7 @@ static int radeonfb_blank (int blank, struct fb_info *info)
1048 1046
1049 if (rinfo->asleep) 1047 if (rinfo->asleep)
1050 return 0; 1048 return 0;
1051 1049
1052 return radeon_screen_blank(rinfo, blank, 0); 1050 return radeon_screen_blank(rinfo, blank, 0);
1053} 1051}
1054 1052
@@ -1074,8 +1072,6 @@ static int radeon_setcolreg (unsigned regno, unsigned red, unsigned green,
1074 pindex = regno; 1072 pindex = regno;
1075 1073
1076 if (!rinfo->asleep) { 1074 if (!rinfo->asleep) {
1077 radeon_fifo_wait(9);
1078
1079 if (rinfo->bpp == 16) { 1075 if (rinfo->bpp == 16) {
1080 pindex = regno * 8; 1076 pindex = regno * 8;
1081 1077
@@ -1244,8 +1240,6 @@ static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_reg
1244{ 1240{
1245 int i; 1241 int i;
1246 1242
1247 radeon_fifo_wait(20);
1248
1249 /* Workaround from XFree */ 1243 /* Workaround from XFree */
1250 if (rinfo->is_mobility) { 1244 if (rinfo->is_mobility) {
1251 /* A temporal workaround for the occational blanking on certain laptop 1245 /* A temporal workaround for the occational blanking on certain laptop
@@ -1286,11 +1280,10 @@ static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_reg
1286 radeon_pll_errata_after_data(rinfo); 1280 radeon_pll_errata_after_data(rinfo);
1287 1281
1288 /* Set PPLL ref. div */ 1282 /* Set PPLL ref. div */
1289 if (rinfo->family == CHIP_FAMILY_R300 || 1283 if (IS_R300_VARIANT(rinfo) ||
1290 rinfo->family == CHIP_FAMILY_RS300 || 1284 rinfo->family == CHIP_FAMILY_RS300 ||
1291 rinfo->family == CHIP_FAMILY_R350 || 1285 rinfo->family == CHIP_FAMILY_RS400 ||
1292 rinfo->family == CHIP_FAMILY_RV350 || 1286 rinfo->family == CHIP_FAMILY_RS480) {
1293 rinfo->family == CHIP_FAMILY_RV380 ) {
1294 if (mode->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) { 1287 if (mode->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) {
1295 /* When restoring console mode, use saved PPLL_REF_DIV 1288 /* When restoring console mode, use saved PPLL_REF_DIV
1296 * setting. 1289 * setting.
@@ -1342,7 +1335,7 @@ static void radeon_lvds_timer_func(unsigned long data)
1342{ 1335{
1343 struct radeonfb_info *rinfo = (struct radeonfb_info *)data; 1336 struct radeonfb_info *rinfo = (struct radeonfb_info *)data;
1344 1337
1345 radeon_engine_idle(); 1338 radeon_engine_idle(rinfo);
1346 1339
1347 OUTREG(LVDS_GEN_CNTL, rinfo->pending_lvds_gen_cntl); 1340 OUTREG(LVDS_GEN_CNTL, rinfo->pending_lvds_gen_cntl);
1348} 1341}
@@ -1360,10 +1353,11 @@ void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode,
1360 if (nomodeset) 1353 if (nomodeset)
1361 return; 1354 return;
1362 1355
1356 radeon_engine_idle(rinfo);
1357
1363 if (!regs_only) 1358 if (!regs_only)
1364 radeon_screen_blank(rinfo, FB_BLANK_NORMAL, 0); 1359 radeon_screen_blank(rinfo, FB_BLANK_NORMAL, 0);
1365 1360
1366 radeon_fifo_wait(31);
1367 for (i=0; i<10; i++) 1361 for (i=0; i<10; i++)
1368 OUTREG(common_regs[i].reg, common_regs[i].val); 1362 OUTREG(common_regs[i].reg, common_regs[i].val);
1369 1363
@@ -1391,7 +1385,6 @@ void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode,
1391 radeon_write_pll_regs(rinfo, mode); 1385 radeon_write_pll_regs(rinfo, mode);
1392 1386
1393 if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) { 1387 if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
1394 radeon_fifo_wait(10);
1395 OUTREG(FP_CRTC_H_TOTAL_DISP, mode->fp_crtc_h_total_disp); 1388 OUTREG(FP_CRTC_H_TOTAL_DISP, mode->fp_crtc_h_total_disp);
1396 OUTREG(FP_CRTC_V_TOTAL_DISP, mode->fp_crtc_v_total_disp); 1389 OUTREG(FP_CRTC_V_TOTAL_DISP, mode->fp_crtc_v_total_disp);
1397 OUTREG(FP_H_SYNC_STRT_WID, mode->fp_h_sync_strt_wid); 1390 OUTREG(FP_H_SYNC_STRT_WID, mode->fp_h_sync_strt_wid);
@@ -1406,7 +1399,6 @@ void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode,
1406 if (!regs_only) 1399 if (!regs_only)
1407 radeon_screen_blank(rinfo, FB_BLANK_UNBLANK, 0); 1400 radeon_screen_blank(rinfo, FB_BLANK_UNBLANK, 0);
1408 1401
1409 radeon_fifo_wait(2);
1410 OUTPLL(VCLK_ECP_CNTL, mode->vclk_ecp_cntl); 1402 OUTPLL(VCLK_ECP_CNTL, mode->vclk_ecp_cntl);
1411 1403
1412 return; 1404 return;
@@ -1461,10 +1453,7 @@ static void radeon_calc_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs
1461 /* Not all chip revs have the same format for this register, 1453 /* Not all chip revs have the same format for this register,
1462 * extract the source selection 1454 * extract the source selection
1463 */ 1455 */
1464 if (rinfo->family == CHIP_FAMILY_R200 || 1456 if (rinfo->family == CHIP_FAMILY_R200 || IS_R300_VARIANT(rinfo)) {
1465 rinfo->family == CHIP_FAMILY_R300 ||
1466 rinfo->family == CHIP_FAMILY_R350 ||
1467 rinfo->family == CHIP_FAMILY_RV350) {
1468 source = (fp2_gen_cntl >> 10) & 0x3; 1457 source = (fp2_gen_cntl >> 10) & 0x3;
1469 /* sourced from transform unit, check for transform unit 1458 /* sourced from transform unit, check for transform unit
1470 * own source 1459 * own source
@@ -1560,7 +1549,7 @@ static int radeonfb_set_par(struct fb_info *info)
1560 /* We always want engine to be idle on a mode switch, even 1549 /* We always want engine to be idle on a mode switch, even
1561 * if we won't actually change the mode 1550 * if we won't actually change the mode
1562 */ 1551 */
1563 radeon_engine_idle(); 1552 radeon_engine_idle(rinfo);
1564 1553
1565 hSyncStart = mode->xres + mode->right_margin; 1554 hSyncStart = mode->xres + mode->right_margin;
1566 hSyncEnd = hSyncStart + mode->hsync_len; 1555 hSyncEnd = hSyncStart + mode->hsync_len;
@@ -1855,7 +1844,6 @@ static int radeonfb_set_par(struct fb_info *info)
1855 return 0; 1844 return 0;
1856} 1845}
1857 1846
1858
1859static struct fb_ops radeonfb_ops = { 1847static struct fb_ops radeonfb_ops = {
1860 .owner = THIS_MODULE, 1848 .owner = THIS_MODULE,
1861 .fb_check_var = radeonfb_check_var, 1849 .fb_check_var = radeonfb_check_var,
@@ -1879,6 +1867,7 @@ static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo)
1879 info->par = rinfo; 1867 info->par = rinfo;
1880 info->pseudo_palette = rinfo->pseudo_palette; 1868 info->pseudo_palette = rinfo->pseudo_palette;
1881 info->flags = FBINFO_DEFAULT 1869 info->flags = FBINFO_DEFAULT
1870 | FBINFO_HWACCEL_IMAGEBLIT
1882 | FBINFO_HWACCEL_COPYAREA 1871 | FBINFO_HWACCEL_COPYAREA
1883 | FBINFO_HWACCEL_FILLRECT 1872 | FBINFO_HWACCEL_FILLRECT
1884 | FBINFO_HWACCEL_XPAN 1873 | FBINFO_HWACCEL_XPAN
@@ -2005,11 +1994,11 @@ static void radeon_identify_vram(struct radeonfb_info *rinfo)
2005 (rinfo->family == CHIP_FAMILY_RS200) || 1994 (rinfo->family == CHIP_FAMILY_RS200) ||
2006 (rinfo->family == CHIP_FAMILY_RS300) || 1995 (rinfo->family == CHIP_FAMILY_RS300) ||
2007 (rinfo->family == CHIP_FAMILY_RC410) || 1996 (rinfo->family == CHIP_FAMILY_RC410) ||
1997 (rinfo->family == CHIP_FAMILY_RS400) ||
2008 (rinfo->family == CHIP_FAMILY_RS480) ) { 1998 (rinfo->family == CHIP_FAMILY_RS480) ) {
2009 u32 tom = INREG(NB_TOM); 1999 u32 tom = INREG(NB_TOM);
2010 tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024); 2000 tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024);
2011 2001
2012 radeon_fifo_wait(6);
2013 OUTREG(MC_FB_LOCATION, tom); 2002 OUTREG(MC_FB_LOCATION, tom);
2014 OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16); 2003 OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
2015 OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16); 2004 OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
diff --git a/drivers/video/aty/radeon_i2c.c b/drivers/video/aty/radeon_i2c.c
index 8c8fa35f1b7c..2c5567175dca 100644
--- a/drivers/video/aty/radeon_i2c.c
+++ b/drivers/video/aty/radeon_i2c.c
@@ -139,12 +139,8 @@ void radeon_delete_i2c_busses(struct radeonfb_info *rinfo)
139int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn, 139int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn,
140 u8 **out_edid) 140 u8 **out_edid)
141{ 141{
142 u32 reg = rinfo->i2c[conn-1].ddc_reg;
143 u8 *edid; 142 u8 *edid;
144 143
145 OUTREG(reg, INREG(reg) &
146 ~(VGA_DDC_DATA_OUTPUT | VGA_DDC_CLK_OUTPUT));
147
148 edid = fb_ddc_read(&rinfo->i2c[conn-1].adapter); 144 edid = fb_ddc_read(&rinfo->i2c[conn-1].adapter);
149 145
150 if (out_edid) 146 if (out_edid)
diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c
index 675abdafc2d8..3df5015f1d13 100644
--- a/drivers/video/aty/radeon_pm.c
+++ b/drivers/video/aty/radeon_pm.c
@@ -2653,9 +2653,9 @@ int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
2653 2653
2654 if (!(info->flags & FBINFO_HWACCEL_DISABLED)) { 2654 if (!(info->flags & FBINFO_HWACCEL_DISABLED)) {
2655 /* Make sure engine is reset */ 2655 /* Make sure engine is reset */
2656 radeon_engine_idle(); 2656 radeon_engine_idle(rinfo);
2657 radeonfb_engine_reset(rinfo); 2657 radeonfb_engine_reset(rinfo);
2658 radeon_engine_idle(); 2658 radeon_engine_idle(rinfo);
2659 } 2659 }
2660 2660
2661 /* Blank display and LCD */ 2661 /* Blank display and LCD */
@@ -2767,7 +2767,7 @@ int radeonfb_pci_resume(struct pci_dev *pdev)
2767 2767
2768 rinfo->asleep = 0; 2768 rinfo->asleep = 0;
2769 } else 2769 } else
2770 radeon_engine_idle(); 2770 radeon_engine_idle(rinfo);
2771 2771
2772 /* Restore display & engine */ 2772 /* Restore display & engine */
2773 radeon_write_mode (rinfo, &rinfo->state, 1); 2773 radeon_write_mode (rinfo, &rinfo->state, 1);
diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/aty/radeonfb.h
index ccbfffd12805..ea0b5b47acaf 100644
--- a/drivers/video/aty/radeonfb.h
+++ b/drivers/video/aty/radeonfb.h
@@ -53,6 +53,7 @@ enum radeon_family {
53 CHIP_FAMILY_RV380, /* RV370/RV380/M22/M24 */ 53 CHIP_FAMILY_RV380, /* RV370/RV380/M22/M24 */
54 CHIP_FAMILY_R420, /* R420/R423/M18 */ 54 CHIP_FAMILY_R420, /* R420/R423/M18 */
55 CHIP_FAMILY_RC410, 55 CHIP_FAMILY_RC410,
56 CHIP_FAMILY_RS400,
56 CHIP_FAMILY_RS480, 57 CHIP_FAMILY_RS480,
57 CHIP_FAMILY_LAST, 58 CHIP_FAMILY_LAST,
58}; 59};
@@ -335,7 +336,15 @@ struct radeonfb_info {
335 int mon2_type; 336 int mon2_type;
336 u8 *mon2_EDID; 337 u8 *mon2_EDID;
337 338
338 u32 dp_gui_master_cntl; 339 /* accel bits */
340 u32 dp_gui_mc_base;
341 u32 dp_gui_mc_cache;
342 u32 dp_cntl_cache;
343 u32 dp_brush_fg_cache;
344 u32 dp_brush_bg_cache;
345 u32 dp_src_fg_cache;
346 u32 dp_src_bg_cache;
347 u32 fifo_free;
339 348
340 struct pll_info pll; 349 struct pll_info pll;
341 350
@@ -347,6 +356,7 @@ struct radeonfb_info {
347 int lock_blank; 356 int lock_blank;
348 int dynclk; 357 int dynclk;
349 int no_schedule; 358 int no_schedule;
359 int gfx_mode;
350 enum radeon_pm_mode pm_mode; 360 enum radeon_pm_mode pm_mode;
351 reinit_function_ptr reinit_func; 361 reinit_function_ptr reinit_func;
352 362
@@ -391,8 +401,14 @@ static inline void _radeon_msleep(struct radeonfb_info *rinfo, unsigned long ms)
391#define OUTREG8(addr,val) writeb(val, (rinfo->mmio_base)+addr) 401#define OUTREG8(addr,val) writeb(val, (rinfo->mmio_base)+addr)
392#define INREG16(addr) readw((rinfo->mmio_base)+addr) 402#define INREG16(addr) readw((rinfo->mmio_base)+addr)
393#define OUTREG16(addr,val) writew(val, (rinfo->mmio_base)+addr) 403#define OUTREG16(addr,val) writew(val, (rinfo->mmio_base)+addr)
404
405#ifdef CONFIG_PPC
406#define INREG(addr) ({ eieio(); ld_le32(rinfo->mmio_base+(addr)); })
407#define OUTREG(addr,val) do { eieio(); st_le32(rinfo->mmio_base+(addr),(val)); } while(0)
408#else
394#define INREG(addr) readl((rinfo->mmio_base)+addr) 409#define INREG(addr) readl((rinfo->mmio_base)+addr)
395#define OUTREG(addr,val) writel(val, (rinfo->mmio_base)+addr) 410#define OUTREG(addr,val) writel(val, (rinfo->mmio_base)+addr)
411#endif
396 412
397static inline void _OUTREGP(struct radeonfb_info *rinfo, u32 addr, 413static inline void _OUTREGP(struct radeonfb_info *rinfo, u32 addr,
398 u32 val, u32 mask) 414 u32 val, u32 mask)
@@ -533,16 +549,25 @@ static inline u32 radeon_get_dstbpp(u16 depth)
533/* 549/*
534 * 2D Engine helper routines 550 * 2D Engine helper routines
535 */ 551 */
552
553extern void radeon_fifo_update_and_wait(struct radeonfb_info *rinfo, int entries);
554
536static inline void radeon_engine_flush (struct radeonfb_info *rinfo) 555static inline void radeon_engine_flush (struct radeonfb_info *rinfo)
537{ 556{
538 int i; 557 int i;
539 558
540 /* initiate flush */ 559 /* Initiate flush */
541 OUTREGP(RB2D_DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL, 560 OUTREGP(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL,
542 ~RB2D_DC_FLUSH_ALL); 561 ~RB2D_DC_FLUSH_ALL);
543 562
563 /* Ensure FIFO is empty, ie, make sure the flush commands
564 * has reached the cache
565 */
566 radeon_fifo_update_and_wait(rinfo, 64);
567
568 /* Wait for the flush to complete */
544 for (i=0; i < 2000000; i++) { 569 for (i=0; i < 2000000; i++) {
545 if (!(INREG(RB2D_DSTCACHE_CTLSTAT) & RB2D_DC_BUSY)) 570 if (!(INREG(DSTCACHE_CTLSTAT) & RB2D_DC_BUSY))
546 return; 571 return;
547 udelay(1); 572 udelay(1);
548 } 573 }
@@ -550,25 +575,12 @@ static inline void radeon_engine_flush (struct radeonfb_info *rinfo)
550} 575}
551 576
552 577
553static inline void _radeon_fifo_wait(struct radeonfb_info *rinfo, int entries) 578static inline void radeon_engine_idle(struct radeonfb_info *rinfo)
554{
555 int i;
556
557 for (i=0; i<2000000; i++) {
558 if ((INREG(RBBM_STATUS) & 0x7f) >= entries)
559 return;
560 udelay(1);
561 }
562 printk(KERN_ERR "radeonfb: FIFO Timeout !\n");
563}
564
565
566static inline void _radeon_engine_idle(struct radeonfb_info *rinfo)
567{ 579{
568 int i; 580 int i;
569 581
570 /* ensure FIFO is empty before waiting for idle */ 582 /* ensure FIFO is empty before waiting for idle */
571 _radeon_fifo_wait (rinfo, 64); 583 radeon_fifo_update_and_wait (rinfo, 64);
572 584
573 for (i=0; i<2000000; i++) { 585 for (i=0; i<2000000; i++) {
574 if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) { 586 if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) {
@@ -581,8 +593,6 @@ static inline void _radeon_engine_idle(struct radeonfb_info *rinfo)
581} 593}
582 594
583 595
584#define radeon_engine_idle() _radeon_engine_idle(rinfo)
585#define radeon_fifo_wait(entries) _radeon_fifo_wait(rinfo,entries)
586#define radeon_msleep(ms) _radeon_msleep(rinfo,ms) 596#define radeon_msleep(ms) _radeon_msleep(rinfo,ms)
587 597
588 598
@@ -612,6 +622,7 @@ extern void radeonfb_imageblit(struct fb_info *p, const struct fb_image *image);
612extern int radeonfb_sync(struct fb_info *info); 622extern int radeonfb_sync(struct fb_info *info);
613extern void radeonfb_engine_init (struct radeonfb_info *rinfo); 623extern void radeonfb_engine_init (struct radeonfb_info *rinfo);
614extern void radeonfb_engine_reset(struct radeonfb_info *rinfo); 624extern void radeonfb_engine_reset(struct radeonfb_info *rinfo);
625extern void radeon_fixup_mem_offset(struct radeonfb_info *rinfo);
615 626
616/* Other functions */ 627/* Other functions */
617extern int radeon_screen_blank(struct radeonfb_info *rinfo, int blank, int mode_switch); 628extern int radeon_screen_blank(struct radeonfb_info *rinfo, int blank, int mode_switch);
diff --git a/drivers/video/carminefb.c b/drivers/video/carminefb.c
index e15bb447440a..c9b191319a9a 100644
--- a/drivers/video/carminefb.c
+++ b/drivers/video/carminefb.c
@@ -535,7 +535,7 @@ static struct fb_ops carminefb_ops = {
535 .fb_setcolreg = carmine_setcolreg, 535 .fb_setcolreg = carmine_setcolreg,
536}; 536};
537 537
538static int alloc_carmine_fb(void __iomem *regs, void __iomem *smem_base, 538static int __devinit alloc_carmine_fb(void __iomem *regs, void __iomem *smem_base,
539 int smem_offset, struct device *device, struct fb_info **rinfo) 539 int smem_offset, struct device *device, struct fb_info **rinfo)
540{ 540{
541 int ret; 541 int ret;
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index e729fb279645..048b139f0e50 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -327,29 +327,7 @@ static const struct {
327#endif /* CONFIG_ZORRO */ 327#endif /* CONFIG_ZORRO */
328 328
329struct cirrusfb_regs { 329struct cirrusfb_regs {
330 long freq; 330 int multiplexing;
331 long nom;
332 long den;
333 long div;
334 long multiplexing;
335 long mclk;
336 long divMCLK;
337
338 long HorizRes; /* The x resolution in pixel */
339 long HorizTotal;
340 long HorizDispEnd;
341 long HorizBlankStart;
342 long HorizBlankEnd;
343 long HorizSyncStart;
344 long HorizSyncEnd;
345
346 long VertRes; /* the physical y resolution in scanlines */
347 long VertTotal;
348 long VertDispEnd;
349 long VertSyncStart;
350 long VertSyncEnd;
351 long VertBlankStart;
352 long VertBlankEnd;
353}; 331};
354 332
355#ifdef CIRRUSFB_DEBUG 333#ifdef CIRRUSFB_DEBUG
@@ -367,110 +345,13 @@ struct cirrusfb_info {
367 345
368 struct cirrusfb_regs currentmode; 346 struct cirrusfb_regs currentmode;
369 int blank_mode; 347 int blank_mode;
348 u32 pseudo_palette[16];
370 349
371 u32 pseudo_palette[16];
372
373#ifdef CONFIG_ZORRO
374 struct zorro_dev *zdev;
375#endif
376#ifdef CONFIG_PCI
377 struct pci_dev *pdev;
378#endif
379 void (*unmap)(struct fb_info *info); 350 void (*unmap)(struct fb_info *info);
380}; 351};
381 352
382static unsigned cirrusfb_def_mode = 1; 353static int noaccel __devinitdata;
383static int noaccel; 354static char *mode_option __devinitdata = "640x480@60";
384
385/*
386 * Predefined Video Modes
387 */
388
389static const struct {
390 const char *name;
391 struct fb_var_screeninfo var;
392} cirrusfb_predefined[] = {
393 {
394 /* autodetect mode */
395 .name = "Autodetect",
396 }, {
397 /* 640x480, 31.25 kHz, 60 Hz, 25 MHz PixClock */
398 .name = "640x480",
399 .var = {
400 .xres = 640,
401 .yres = 480,
402 .xres_virtual = 640,
403 .yres_virtual = 480,
404 .bits_per_pixel = 8,
405 .red = { .length = 8 },
406 .green = { .length = 8 },
407 .blue = { .length = 8 },
408 .width = -1,
409 .height = -1,
410 .pixclock = 40000,
411 .left_margin = 48,
412 .right_margin = 16,
413 .upper_margin = 32,
414 .lower_margin = 8,
415 .hsync_len = 96,
416 .vsync_len = 4,
417 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
418 .vmode = FB_VMODE_NONINTERLACED
419 }
420 }, {
421 /* 800x600, 48 kHz, 76 Hz, 50 MHz PixClock */
422 .name = "800x600",
423 .var = {
424 .xres = 800,
425 .yres = 600,
426 .xres_virtual = 800,
427 .yres_virtual = 600,
428 .bits_per_pixel = 8,
429 .red = { .length = 8 },
430 .green = { .length = 8 },
431 .blue = { .length = 8 },
432 .width = -1,
433 .height = -1,
434 .pixclock = 20000,
435 .left_margin = 128,
436 .right_margin = 16,
437 .upper_margin = 24,
438 .lower_margin = 2,
439 .hsync_len = 96,
440 .vsync_len = 6,
441 .vmode = FB_VMODE_NONINTERLACED
442 }
443 }, {
444 /*
445 * Modeline from XF86Config:
446 * Mode "1024x768" 80 1024 1136 1340 1432 768 770 774 805
447 */
448 /* 1024x768, 55.8 kHz, 70 Hz, 80 MHz PixClock */
449 .name = "1024x768",
450 .var = {
451 .xres = 1024,
452 .yres = 768,
453 .xres_virtual = 1024,
454 .yres_virtual = 768,
455 .bits_per_pixel = 8,
456 .red = { .length = 8 },
457 .green = { .length = 8 },
458 .blue = { .length = 8 },
459 .width = -1,
460 .height = -1,
461 .pixclock = 12500,
462 .left_margin = 144,
463 .right_margin = 32,
464 .upper_margin = 30,
465 .lower_margin = 2,
466 .hsync_len = 192,
467 .vsync_len = 6,
468 .vmode = FB_VMODE_NONINTERLACED
469 }
470 }
471};
472
473#define NUM_TOTAL_MODES ARRAY_SIZE(cirrusfb_predefined)
474 355
475/****************************************************************************/ 356/****************************************************************************/
476/**** BEGIN PROTOTYPES ******************************************************/ 357/**** BEGIN PROTOTYPES ******************************************************/
@@ -514,10 +395,6 @@ static struct fb_ops cirrusfb_ops = {
514 .fb_imageblit = cirrusfb_imageblit, 395 .fb_imageblit = cirrusfb_imageblit,
515}; 396};
516 397
517/*--- Hardware Specific Routines -------------------------------------------*/
518static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
519 struct cirrusfb_regs *regs,
520 struct fb_info *info);
521/*--- Internal routines ----------------------------------------------------*/ 398/*--- Internal routines ----------------------------------------------------*/
522static void init_vgachip(struct fb_info *info); 399static void init_vgachip(struct fb_info *info);
523static void switch_monitor(struct cirrusfb_info *cinfo, int on); 400static void switch_monitor(struct cirrusfb_info *cinfo, int on);
@@ -546,9 +423,7 @@ static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
546 u_short width, u_short height, 423 u_short width, u_short height,
547 u_char color, u_short line_length); 424 u_char color, u_short line_length);
548 425
549static void bestclock(long freq, long *best, 426static void bestclock(long freq, int *nom, int *den, int *div);
550 long *nom, long *den,
551 long *div, long maxfreq);
552 427
553#ifdef CIRRUSFB_DEBUG 428#ifdef CIRRUSFB_DEBUG
554static void cirrusfb_dump(void); 429static void cirrusfb_dump(void);
@@ -584,45 +459,28 @@ static int cirrusfb_release(struct fb_info *info, int user)
584/****************************************************************************/ 459/****************************************************************************/
585/**** BEGIN Hardware specific Routines **************************************/ 460/**** BEGIN Hardware specific Routines **************************************/
586 461
587/* Get a good MCLK value */ 462/* Check if the MCLK is not a better clock source */
588static long cirrusfb_get_mclk(long freq, int bpp, long *div) 463static int cirrusfb_check_mclk(struct cirrusfb_info *cinfo, long freq)
589{ 464{
590 long mclk; 465 long mclk = vga_rseq(cinfo->regbase, CL_SEQR1F) & 0x3f;
591 466
592 assert(div != NULL); 467 /* Read MCLK value */
593 468 mclk = (14318 * mclk) >> 3;
594 /* Calculate MCLK, in case VCLK is high enough to require > 50MHz. 469 DPRINTK("Read MCLK of %ld kHz\n", mclk);
595 * Assume a 64-bit data path for now. The formula is:
596 * ((B * PCLK * 2)/W) * 1.2
597 * B = bytes per pixel, PCLK = pixclock, W = data width in bytes */
598 mclk = ((bpp / 8) * freq * 2) / 4;
599 mclk = (mclk * 12) / 10;
600 if (mclk < 50000)
601 mclk = 50000;
602 DPRINTK("Use MCLK of %ld kHz\n", mclk);
603
604 /* Calculate value for SR1F. Multiply by 2 so we can round up. */
605 mclk = ((mclk * 16) / 14318);
606 mclk = (mclk + 1) / 2;
607 DPRINTK("Set SR1F[5:0] to 0x%lx\n", mclk);
608 470
609 /* Determine if we should use MCLK instead of VCLK, and if so, what we 471 /* Determine if we should use MCLK instead of VCLK, and if so, what we
610 * should divide it by to get VCLK */ 472 * should divide it by to get VCLK
611 switch (freq) { 473 */
612 case 24751 ... 25249: 474
613 *div = 2; 475 if (abs(freq - mclk) < 250) {
614 DPRINTK("Using VCLK = MCLK/2\n");
615 break;
616 case 49501 ... 50499:
617 *div = 1;
618 DPRINTK("Using VCLK = MCLK\n"); 476 DPRINTK("Using VCLK = MCLK\n");
619 break; 477 return 1;
620 default: 478 } else if (abs(freq - (mclk / 2)) < 250) {
621 *div = 0; 479 DPRINTK("Using VCLK = MCLK/2\n");
622 break; 480 return 2;
623 } 481 }
624 482
625 return mclk; 483 return 0;
626} 484}
627 485
628static int cirrusfb_check_var(struct fb_var_screeninfo *var, 486static int cirrusfb_check_var(struct fb_var_screeninfo *var,
@@ -638,7 +496,6 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
638 break; /* 8 pixel per byte, only 1/4th of mem usable */ 496 break; /* 8 pixel per byte, only 1/4th of mem usable */
639 case 8: 497 case 8:
640 case 16: 498 case 16:
641 case 24:
642 case 32: 499 case 32:
643 break; /* 1 pixel == 1 byte */ 500 break; /* 1 pixel == 1 byte */
644 default: 501 default:
@@ -713,7 +570,6 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
713 var->blue.length = 5; 570 var->blue.length = 5;
714 break; 571 break;
715 572
716 case 24:
717 case 32: 573 case 32:
718 if (isPReP) { 574 if (isPReP) {
719 var->red.offset = 8; 575 var->red.offset = 8;
@@ -767,8 +623,6 @@ static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
767 long maxclock; 623 long maxclock;
768 int maxclockidx = var->bits_per_pixel >> 3; 624 int maxclockidx = var->bits_per_pixel >> 3;
769 struct cirrusfb_info *cinfo = info->par; 625 struct cirrusfb_info *cinfo = info->par;
770 int xres, hfront, hsync, hback;
771 int yres, vfront, vsync, vback;
772 626
773 switch (var->bits_per_pixel) { 627 switch (var->bits_per_pixel) {
774 case 1: 628 case 1:
@@ -782,10 +636,9 @@ static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
782 break; 636 break;
783 637
784 case 16: 638 case 16:
785 case 24:
786 case 32: 639 case 32:
787 info->fix.line_length = var->xres_virtual * maxclockidx; 640 info->fix.line_length = var->xres_virtual * maxclockidx;
788 info->fix.visual = FB_VISUAL_DIRECTCOLOR; 641 info->fix.visual = FB_VISUAL_TRUECOLOR;
789 break; 642 break;
790 643
791 default: 644 default:
@@ -827,90 +680,33 @@ static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
827 switch (var->bits_per_pixel) { 680 switch (var->bits_per_pixel) {
828 case 16: 681 case 16:
829 case 32: 682 case 32:
830 if (regs->HorizRes <= 800) 683 if (var->xres <= 800)
831 /* Xbh has this type of clock for 32-bit */ 684 /* Xbh has this type of clock for 32-bit */
832 freq /= 2; 685 freq /= 2;
833 break; 686 break;
834 } 687 }
835#endif 688#endif
836
837 bestclock(freq, &regs->freq, &regs->nom, &regs->den, &regs->div,
838 maxclock);
839 regs->mclk = cirrusfb_get_mclk(freq, var->bits_per_pixel,
840 &regs->divMCLK);
841
842 xres = var->xres;
843 hfront = var->right_margin;
844 hsync = var->hsync_len;
845 hback = var->left_margin;
846
847 yres = var->yres;
848 vfront = var->lower_margin;
849 vsync = var->vsync_len;
850 vback = var->upper_margin;
851
852 if (var->vmode & FB_VMODE_DOUBLE) {
853 yres *= 2;
854 vfront *= 2;
855 vsync *= 2;
856 vback *= 2;
857 } else if (var->vmode & FB_VMODE_INTERLACED) {
858 yres = (yres + 1) / 2;
859 vfront = (vfront + 1) / 2;
860 vsync = (vsync + 1) / 2;
861 vback = (vback + 1) / 2;
862 }
863 regs->HorizRes = xres;
864 regs->HorizTotal = (xres + hfront + hsync + hback) / 8 - 5;
865 regs->HorizDispEnd = xres / 8 - 1;
866 regs->HorizBlankStart = xres / 8;
867 /* does not count with "-5" */
868 regs->HorizBlankEnd = regs->HorizTotal + 5;
869 regs->HorizSyncStart = (xres + hfront) / 8 + 1;
870 regs->HorizSyncEnd = (xres + hfront + hsync) / 8 + 1;
871
872 regs->VertRes = yres;
873 regs->VertTotal = yres + vfront + vsync + vback - 2;
874 regs->VertDispEnd = yres - 1;
875 regs->VertBlankStart = yres;
876 regs->VertBlankEnd = regs->VertTotal;
877 regs->VertSyncStart = yres + vfront - 1;
878 regs->VertSyncEnd = yres + vfront + vsync - 1;
879
880 if (regs->VertRes >= 1024) {
881 regs->VertTotal /= 2;
882 regs->VertSyncStart /= 2;
883 regs->VertSyncEnd /= 2;
884 regs->VertDispEnd /= 2;
885 }
886 if (regs->multiplexing) {
887 regs->HorizTotal /= 2;
888 regs->HorizSyncStart /= 2;
889 regs->HorizSyncEnd /= 2;
890 regs->HorizDispEnd /= 2;
891 }
892
893 return 0; 689 return 0;
894} 690}
895 691
896static void cirrusfb_set_mclk(const struct cirrusfb_info *cinfo, int val, 692static void cirrusfb_set_mclk_as_source(const struct cirrusfb_info *cinfo,
897 int div) 693 int div)
898{ 694{
695 unsigned char old1f, old1e;
899 assert(cinfo != NULL); 696 assert(cinfo != NULL);
697 old1f = vga_rseq(cinfo->regbase, CL_SEQR1F) & ~0x40;
900 698
901 if (div == 2) { 699 if (div) {
902 /* VCLK = MCLK/2 */ 700 DPRINTK("Set %s as pixclock source.\n",
903 unsigned char old = vga_rseq(cinfo->regbase, CL_SEQR1E); 701 (div == 2) ? "MCLK/2" : "MCLK");
904 vga_wseq(cinfo->regbase, CL_SEQR1E, old | 0x1); 702 old1f |= 0x40;
905 vga_wseq(cinfo->regbase, CL_SEQR1F, 0x40 | (val & 0x3f)); 703 old1e = vga_rseq(cinfo->regbase, CL_SEQR1E) & ~0x1;
906 } else if (div == 1) { 704 if (div == 2)
907 /* VCLK = MCLK */ 705 old1e |= 1;
908 unsigned char old = vga_rseq(cinfo->regbase, CL_SEQR1E); 706
909 vga_wseq(cinfo->regbase, CL_SEQR1E, old & ~0x1); 707 vga_wseq(cinfo->regbase, CL_SEQR1E, old1e);
910 vga_wseq(cinfo->regbase, CL_SEQR1F, 0x40 | (val & 0x3f));
911 } else {
912 vga_wseq(cinfo->regbase, CL_SEQR1F, val & 0x3f);
913 } 708 }
709 vga_wseq(cinfo->regbase, CL_SEQR1F, old1f);
914} 710}
915 711
916/************************************************************************* 712/*************************************************************************
@@ -927,6 +723,10 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
927 unsigned char tmp; 723 unsigned char tmp;
928 int offset = 0, err; 724 int offset = 0, err;
929 const struct cirrusfb_board_info_rec *bi; 725 const struct cirrusfb_board_info_rec *bi;
726 int hdispend, hsyncstart, hsyncend, htotal;
727 int yres, vdispend, vsyncstart, vsyncend, vtotal;
728 long freq;
729 int nom, den, div;
930 730
931 DPRINTK("ENTER\n"); 731 DPRINTK("ENTER\n");
932 DPRINTK("Requested mode: %dx%dx%d\n", 732 DPRINTK("Requested mode: %dx%dx%d\n",
@@ -944,76 +744,117 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
944 744
945 bi = &cirrusfb_board_info[cinfo->btype]; 745 bi = &cirrusfb_board_info[cinfo->btype];
946 746
747 hsyncstart = var->xres + var->right_margin;
748 hsyncend = hsyncstart + var->hsync_len;
749 htotal = (hsyncend + var->left_margin) / 8 - 5;
750 hdispend = var->xres / 8 - 1;
751 hsyncstart = hsyncstart / 8 + 1;
752 hsyncend = hsyncend / 8 + 1;
753
754 yres = var->yres;
755 vsyncstart = yres + var->lower_margin;
756 vsyncend = vsyncstart + var->vsync_len;
757 vtotal = vsyncend + var->upper_margin;
758 vdispend = yres - 1;
759
760 if (var->vmode & FB_VMODE_DOUBLE) {
761 yres *= 2;
762 vsyncstart *= 2;
763 vsyncend *= 2;
764 vtotal *= 2;
765 } else if (var->vmode & FB_VMODE_INTERLACED) {
766 yres = (yres + 1) / 2;
767 vsyncstart = (vsyncstart + 1) / 2;
768 vsyncend = (vsyncend + 1) / 2;
769 vtotal = (vtotal + 1) / 2;
770 }
771
772 vtotal -= 2;
773 vsyncstart -= 1;
774 vsyncend -= 1;
775
776 if (yres >= 1024) {
777 vtotal /= 2;
778 vsyncstart /= 2;
779 vsyncend /= 2;
780 vdispend /= 2;
781 }
782 if (regs.multiplexing) {
783 htotal /= 2;
784 hsyncstart /= 2;
785 hsyncend /= 2;
786 hdispend /= 2;
787 }
947 /* unlock register VGA_CRTC_H_TOTAL..CRT7 */ 788 /* unlock register VGA_CRTC_H_TOTAL..CRT7 */
948 vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20); /* previously: 0x00) */ 789 vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20); /* previously: 0x00) */
949 790
950 /* if debugging is enabled, all parameters get output before writing */ 791 /* if debugging is enabled, all parameters get output before writing */
951 DPRINTK("CRT0: %ld\n", regs.HorizTotal); 792 DPRINTK("CRT0: %d\n", htotal);
952 vga_wcrt(regbase, VGA_CRTC_H_TOTAL, regs.HorizTotal); 793 vga_wcrt(regbase, VGA_CRTC_H_TOTAL, htotal);
953 794
954 DPRINTK("CRT1: %ld\n", regs.HorizDispEnd); 795 DPRINTK("CRT1: %d\n", hdispend);
955 vga_wcrt(regbase, VGA_CRTC_H_DISP, regs.HorizDispEnd); 796 vga_wcrt(regbase, VGA_CRTC_H_DISP, hdispend);
956 797
957 DPRINTK("CRT2: %ld\n", regs.HorizBlankStart); 798 DPRINTK("CRT2: %d\n", var->xres / 8);
958 vga_wcrt(regbase, VGA_CRTC_H_BLANK_START, regs.HorizBlankStart); 799 vga_wcrt(regbase, VGA_CRTC_H_BLANK_START, var->xres / 8);
959 800
960 /* + 128: Compatible read */ 801 /* + 128: Compatible read */
961 DPRINTK("CRT3: 128+%ld\n", regs.HorizBlankEnd % 32); 802 DPRINTK("CRT3: 128+%d\n", (htotal + 5) % 32);
962 vga_wcrt(regbase, VGA_CRTC_H_BLANK_END, 803 vga_wcrt(regbase, VGA_CRTC_H_BLANK_END,
963 128 + (regs.HorizBlankEnd % 32)); 804 128 + ((htotal + 5) % 32));
964 805
965 DPRINTK("CRT4: %ld\n", regs.HorizSyncStart); 806 DPRINTK("CRT4: %d\n", hsyncstart);
966 vga_wcrt(regbase, VGA_CRTC_H_SYNC_START, regs.HorizSyncStart); 807 vga_wcrt(regbase, VGA_CRTC_H_SYNC_START, hsyncstart);
967 808
968 tmp = regs.HorizSyncEnd % 32; 809 tmp = hsyncend % 32;
969 if (regs.HorizBlankEnd & 32) 810 if ((htotal + 5) & 32)
970 tmp += 128; 811 tmp += 128;
971 DPRINTK("CRT5: %d\n", tmp); 812 DPRINTK("CRT5: %d\n", tmp);
972 vga_wcrt(regbase, VGA_CRTC_H_SYNC_END, tmp); 813 vga_wcrt(regbase, VGA_CRTC_H_SYNC_END, tmp);
973 814
974 DPRINTK("CRT6: %ld\n", regs.VertTotal & 0xff); 815 DPRINTK("CRT6: %d\n", vtotal & 0xff);
975 vga_wcrt(regbase, VGA_CRTC_V_TOTAL, (regs.VertTotal & 0xff)); 816 vga_wcrt(regbase, VGA_CRTC_V_TOTAL, vtotal & 0xff);
976 817
977 tmp = 16; /* LineCompare bit #9 */ 818 tmp = 16; /* LineCompare bit #9 */
978 if (regs.VertTotal & 256) 819 if (vtotal & 256)
979 tmp |= 1; 820 tmp |= 1;
980 if (regs.VertDispEnd & 256) 821 if (vdispend & 256)
981 tmp |= 2; 822 tmp |= 2;
982 if (regs.VertSyncStart & 256) 823 if (vsyncstart & 256)
983 tmp |= 4; 824 tmp |= 4;
984 if (regs.VertBlankStart & 256) 825 if ((vdispend + 1) & 256)
985 tmp |= 8; 826 tmp |= 8;
986 if (regs.VertTotal & 512) 827 if (vtotal & 512)
987 tmp |= 32; 828 tmp |= 32;
988 if (regs.VertDispEnd & 512) 829 if (vdispend & 512)
989 tmp |= 64; 830 tmp |= 64;
990 if (regs.VertSyncStart & 512) 831 if (vsyncstart & 512)
991 tmp |= 128; 832 tmp |= 128;
992 DPRINTK("CRT7: %d\n", tmp); 833 DPRINTK("CRT7: %d\n", tmp);
993 vga_wcrt(regbase, VGA_CRTC_OVERFLOW, tmp); 834 vga_wcrt(regbase, VGA_CRTC_OVERFLOW, tmp);
994 835
995 tmp = 0x40; /* LineCompare bit #8 */ 836 tmp = 0x40; /* LineCompare bit #8 */
996 if (regs.VertBlankStart & 512) 837 if ((vdispend + 1) & 512)
997 tmp |= 0x20; 838 tmp |= 0x20;
998 if (var->vmode & FB_VMODE_DOUBLE) 839 if (var->vmode & FB_VMODE_DOUBLE)
999 tmp |= 0x80; 840 tmp |= 0x80;
1000 DPRINTK("CRT9: %d\n", tmp); 841 DPRINTK("CRT9: %d\n", tmp);
1001 vga_wcrt(regbase, VGA_CRTC_MAX_SCAN, tmp); 842 vga_wcrt(regbase, VGA_CRTC_MAX_SCAN, tmp);
1002 843
1003 DPRINTK("CRT10: %ld\n", regs.VertSyncStart & 0xff); 844 DPRINTK("CRT10: %d\n", vsyncstart & 0xff);
1004 vga_wcrt(regbase, VGA_CRTC_V_SYNC_START, regs.VertSyncStart & 0xff); 845 vga_wcrt(regbase, VGA_CRTC_V_SYNC_START, vsyncstart & 0xff);
1005 846
1006 DPRINTK("CRT11: 64+32+%ld\n", regs.VertSyncEnd % 16); 847 DPRINTK("CRT11: 64+32+%d\n", vsyncend % 16);
1007 vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, regs.VertSyncEnd % 16 + 64 + 32); 848 vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, vsyncend % 16 + 64 + 32);
1008 849
1009 DPRINTK("CRT12: %ld\n", regs.VertDispEnd & 0xff); 850 DPRINTK("CRT12: %d\n", vdispend & 0xff);
1010 vga_wcrt(regbase, VGA_CRTC_V_DISP_END, regs.VertDispEnd & 0xff); 851 vga_wcrt(regbase, VGA_CRTC_V_DISP_END, vdispend & 0xff);
1011 852
1012 DPRINTK("CRT15: %ld\n", regs.VertBlankStart & 0xff); 853 DPRINTK("CRT15: %d\n", (vdispend + 1) & 0xff);
1013 vga_wcrt(regbase, VGA_CRTC_V_BLANK_START, regs.VertBlankStart & 0xff); 854 vga_wcrt(regbase, VGA_CRTC_V_BLANK_START, (vdispend + 1) & 0xff);
1014 855
1015 DPRINTK("CRT16: %ld\n", regs.VertBlankEnd & 0xff); 856 DPRINTK("CRT16: %d\n", vtotal & 0xff);
1016 vga_wcrt(regbase, VGA_CRTC_V_BLANK_END, regs.VertBlankEnd & 0xff); 857 vga_wcrt(regbase, VGA_CRTC_V_BLANK_END, vtotal & 0xff);
1017 858
1018 DPRINTK("CRT18: 0xff\n"); 859 DPRINTK("CRT18: 0xff\n");
1019 vga_wcrt(regbase, VGA_CRTC_LINE_COMPARE, 0xff); 860 vga_wcrt(regbase, VGA_CRTC_LINE_COMPARE, 0xff);
@@ -1021,38 +862,53 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
1021 tmp = 0; 862 tmp = 0;
1022 if (var->vmode & FB_VMODE_INTERLACED) 863 if (var->vmode & FB_VMODE_INTERLACED)
1023 tmp |= 1; 864 tmp |= 1;
1024 if (regs.HorizBlankEnd & 64) 865 if ((htotal + 5) & 64)
1025 tmp |= 16; 866 tmp |= 16;
1026 if (regs.HorizBlankEnd & 128) 867 if ((htotal + 5) & 128)
1027 tmp |= 32; 868 tmp |= 32;
1028 if (regs.VertBlankEnd & 256) 869 if (vtotal & 256)
1029 tmp |= 64; 870 tmp |= 64;
1030 if (regs.VertBlankEnd & 512) 871 if (vtotal & 512)
1031 tmp |= 128; 872 tmp |= 128;
1032 873
1033 DPRINTK("CRT1a: %d\n", tmp); 874 DPRINTK("CRT1a: %d\n", tmp);
1034 vga_wcrt(regbase, CL_CRT1A, tmp); 875 vga_wcrt(regbase, CL_CRT1A, tmp);
1035 876
877 freq = PICOS2KHZ(var->pixclock);
878 bestclock(freq, &nom, &den, &div);
879
1036 /* set VCLK0 */ 880 /* set VCLK0 */
1037 /* hardware RefClock: 14.31818 MHz */ 881 /* hardware RefClock: 14.31818 MHz */
1038 /* formula: VClk = (OSC * N) / (D * (1+P)) */ 882 /* formula: VClk = (OSC * N) / (D * (1+P)) */
1039 /* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */ 883 /* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */
1040 884
1041 vga_wseq(regbase, CL_SEQRB, regs.nom); 885 if (cinfo->btype == BT_ALPINE) {
1042 tmp = regs.den << 1; 886 /* if freq is close to mclk or mclk/2 select mclk
1043 if (regs.div != 0) 887 * as clock source
1044 tmp |= 1; 888 */
889 int divMCLK = cirrusfb_check_mclk(cinfo, freq);
890 if (divMCLK) {
891 nom = 0;
892 cirrusfb_set_mclk_as_source(cinfo, divMCLK);
893 }
894 }
895 if (nom) {
896 vga_wseq(regbase, CL_SEQRB, nom);
897 tmp = den << 1;
898 if (div != 0)
899 tmp |= 1;
1045 900
1046 /* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */ 901 /* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */
1047 if ((cinfo->btype == BT_SD64) || 902 if ((cinfo->btype == BT_SD64) ||
1048 (cinfo->btype == BT_ALPINE) || 903 (cinfo->btype == BT_ALPINE) ||
1049 (cinfo->btype == BT_GD5480)) 904 (cinfo->btype == BT_GD5480))
1050 tmp |= 0x80; 905 tmp |= 0x80;
1051 906
1052 DPRINTK("CL_SEQR1B: %ld\n", (long) tmp); 907 DPRINTK("CL_SEQR1B: %ld\n", (long) tmp);
1053 vga_wseq(regbase, CL_SEQR1B, tmp); 908 vga_wseq(regbase, CL_SEQR1B, tmp);
909 }
1054 910
1055 if (regs.VertRes >= 1024) 911 if (yres >= 1024)
1056 /* 1280x1024 */ 912 /* 1280x1024 */
1057 vga_wcrt(regbase, VGA_CRTC_MODE, 0xc7); 913 vga_wcrt(regbase, VGA_CRTC_MODE, 0xc7);
1058 else 914 else
@@ -1066,7 +922,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
1066 /* don't know if it would hurt to also program this if no interlaced */ 922 /* don't know if it would hurt to also program this if no interlaced */
1067 /* mode is used, but I feel better this way.. :-) */ 923 /* mode is used, but I feel better this way.. :-) */
1068 if (var->vmode & FB_VMODE_INTERLACED) 924 if (var->vmode & FB_VMODE_INTERLACED)
1069 vga_wcrt(regbase, VGA_CRTC_REGS, regs.HorizTotal / 2); 925 vga_wcrt(regbase, VGA_CRTC_REGS, htotal / 2);
1070 else 926 else
1071 vga_wcrt(regbase, VGA_CRTC_REGS, 0x00); /* interlace control */ 927 vga_wcrt(regbase, VGA_CRTC_REGS, 0x00); /* interlace control */
1072 928
@@ -1240,7 +1096,6 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
1240 1096
1241 case BT_ALPINE: 1097 case BT_ALPINE:
1242 DPRINTK(" (for GD543x)\n"); 1098 DPRINTK(" (for GD543x)\n");
1243 cirrusfb_set_mclk(cinfo, regs.mclk, regs.divMCLK);
1244 /* We already set SRF and SR1F */ 1099 /* We already set SRF and SR1F */
1245 break; 1100 break;
1246 1101
@@ -1312,11 +1167,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
1312 1167
1313 case BT_ALPINE: 1168 case BT_ALPINE:
1314 DPRINTK(" (for GD543x)\n"); 1169 DPRINTK(" (for GD543x)\n");
1315 if (regs.HorizRes >= 1024) 1170 vga_wseq(regbase, CL_SEQR7, 0xa7);
1316 vga_wseq(regbase, CL_SEQR7, 0xa7);
1317 else
1318 vga_wseq(regbase, CL_SEQR7, 0xa3);
1319 cirrusfb_set_mclk(cinfo, regs.mclk, regs.divMCLK);
1320 break; 1171 break;
1321 1172
1322 case BT_GD5480: 1173 case BT_GD5480:
@@ -1360,7 +1211,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
1360 */ 1211 */
1361 1212
1362 else if (var->bits_per_pixel == 32) { 1213 else if (var->bits_per_pixel == 32) {
1363 DPRINTK("cirrusfb: preparing for 24/32 bit deep display\n"); 1214 DPRINTK("cirrusfb: preparing for 32 bit deep display\n");
1364 switch (cinfo->btype) { 1215 switch (cinfo->btype) {
1365 case BT_SD64: 1216 case BT_SD64:
1366 /* Extended Sequencer Mode: 256c col. mode */ 1217 /* Extended Sequencer Mode: 256c col. mode */
@@ -1394,7 +1245,6 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
1394 case BT_ALPINE: 1245 case BT_ALPINE:
1395 DPRINTK(" (for GD543x)\n"); 1246 DPRINTK(" (for GD543x)\n");
1396 vga_wseq(regbase, CL_SEQR7, 0xa9); 1247 vga_wseq(regbase, CL_SEQR7, 0xa9);
1397 cirrusfb_set_mclk(cinfo, regs.mclk, regs.divMCLK);
1398 break; 1248 break;
1399 1249
1400 case BT_GD5480: 1250 case BT_GD5480:
@@ -1949,8 +1799,6 @@ static void init_vgachip(struct fb_info *info)
1949 /* misc... */ 1799 /* misc... */
1950 WHDR(cinfo, 0); /* Hidden DAC register: - */ 1800 WHDR(cinfo, 0); /* Hidden DAC register: - */
1951 1801
1952 printk(KERN_DEBUG "cirrusfb: This board has %ld bytes of DRAM memory\n",
1953 info->screen_size);
1954 DPRINTK("EXIT\n"); 1802 DPRINTK("EXIT\n");
1955 return; 1803 return;
1956} 1804}
@@ -2122,7 +1970,7 @@ static int release_io_ports;
2122 * based on the DRAM bandwidth bit and DRAM bank switching bit. This 1970 * based on the DRAM bandwidth bit and DRAM bank switching bit. This
2123 * works with 1MB, 2MB and 4MB configurations (which the Motorola boards 1971 * works with 1MB, 2MB and 4MB configurations (which the Motorola boards
2124 * seem to have. */ 1972 * seem to have. */
2125static unsigned int cirrusfb_get_memsize(u8 __iomem *regbase) 1973static unsigned int __devinit cirrusfb_get_memsize(u8 __iomem *regbase)
2126{ 1974{
2127 unsigned long mem; 1975 unsigned long mem;
2128 unsigned char SRF; 1976 unsigned char SRF;
@@ -2188,8 +2036,7 @@ static void get_pci_addrs(const struct pci_dev *pdev,
2188 2036
2189static void cirrusfb_pci_unmap(struct fb_info *info) 2037static void cirrusfb_pci_unmap(struct fb_info *info)
2190{ 2038{
2191 struct cirrusfb_info *cinfo = info->par; 2039 struct pci_dev *pdev = to_pci_dev(info->device);
2192 struct pci_dev *pdev = cinfo->pdev;
2193 2040
2194 iounmap(info->screen_base); 2041 iounmap(info->screen_base);
2195#if 0 /* if system didn't claim this region, we would... */ 2042#if 0 /* if system didn't claim this region, we would... */
@@ -2205,20 +2052,22 @@ static void cirrusfb_pci_unmap(struct fb_info *info)
2205static void __devexit cirrusfb_zorro_unmap(struct fb_info *info) 2052static void __devexit cirrusfb_zorro_unmap(struct fb_info *info)
2206{ 2053{
2207 struct cirrusfb_info *cinfo = info->par; 2054 struct cirrusfb_info *cinfo = info->par;
2208 zorro_release_device(cinfo->zdev); 2055 struct zorro_dev *zdev = to_zorro_dev(info->device);
2056
2057 zorro_release_device(zdev);
2209 2058
2210 if (cinfo->btype == BT_PICASSO4) { 2059 if (cinfo->btype == BT_PICASSO4) {
2211 cinfo->regbase -= 0x600000; 2060 cinfo->regbase -= 0x600000;
2212 iounmap((void *)cinfo->regbase); 2061 iounmap((void *)cinfo->regbase);
2213 iounmap(info->screen_base); 2062 iounmap(info->screen_base);
2214 } else { 2063 } else {
2215 if (zorro_resource_start(cinfo->zdev) > 0x01000000) 2064 if (zorro_resource_start(zdev) > 0x01000000)
2216 iounmap(info->screen_base); 2065 iounmap(info->screen_base);
2217 } 2066 }
2218} 2067}
2219#endif /* CONFIG_ZORRO */ 2068#endif /* CONFIG_ZORRO */
2220 2069
2221static int cirrusfb_set_fbinfo(struct fb_info *info) 2070static int __devinit cirrusfb_set_fbinfo(struct fb_info *info)
2222{ 2071{
2223 struct cirrusfb_info *cinfo = info->par; 2072 struct cirrusfb_info *cinfo = info->par;
2224 struct fb_var_screeninfo *var = &info->var; 2073 struct fb_var_screeninfo *var = &info->var;
@@ -2235,7 +2084,7 @@ static int cirrusfb_set_fbinfo(struct fb_info *info)
2235 if (cinfo->btype == BT_GD5480) { 2084 if (cinfo->btype == BT_GD5480) {
2236 if (var->bits_per_pixel == 16) 2085 if (var->bits_per_pixel == 16)
2237 info->screen_base += 1 * MB_; 2086 info->screen_base += 1 * MB_;
2238 if (var->bits_per_pixel == 24 || var->bits_per_pixel == 32) 2087 if (var->bits_per_pixel == 32)
2239 info->screen_base += 2 * MB_; 2088 info->screen_base += 2 * MB_;
2240 } 2089 }
2241 2090
@@ -2262,7 +2111,7 @@ static int cirrusfb_set_fbinfo(struct fb_info *info)
2262 return 0; 2111 return 0;
2263} 2112}
2264 2113
2265static int cirrusfb_register(struct fb_info *info) 2114static int __devinit cirrusfb_register(struct fb_info *info)
2266{ 2115{
2267 struct cirrusfb_info *cinfo = info->par; 2116 struct cirrusfb_info *cinfo = info->par;
2268 int err; 2117 int err;
@@ -2278,23 +2127,27 @@ static int cirrusfb_register(struct fb_info *info)
2278 /* sanity checks */ 2127 /* sanity checks */
2279 assert(btype != BT_NONE); 2128 assert(btype != BT_NONE);
2280 2129
2130 /* set all the vital stuff */
2131 cirrusfb_set_fbinfo(info);
2132
2281 DPRINTK("cirrusfb: (RAM start set to: 0x%p)\n", info->screen_base); 2133 DPRINTK("cirrusfb: (RAM start set to: 0x%p)\n", info->screen_base);
2282 2134
2283 /* Make pretend we've set the var so our structures are in a "good" */ 2135 err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8);
2284 /* state, even though we haven't written the mode to the hw yet... */ 2136 if (!err) {
2285 info->var = cirrusfb_predefined[cirrusfb_def_mode].var; 2137 DPRINTK("wrong initial video mode\n");
2138 err = -EINVAL;
2139 goto err_dealloc_cmap;
2140 }
2141
2286 info->var.activate = FB_ACTIVATE_NOW; 2142 info->var.activate = FB_ACTIVATE_NOW;
2287 2143
2288 err = cirrusfb_decode_var(&info->var, &cinfo->currentmode, info); 2144 err = cirrusfb_decode_var(&info->var, &cinfo->currentmode, info);
2289 if (err < 0) { 2145 if (err < 0) {
2290 /* should never happen */ 2146 /* should never happen */
2291 DPRINTK("choking on default var... umm, no good.\n"); 2147 DPRINTK("choking on default var... umm, no good.\n");
2292 goto err_unmap_cirrusfb; 2148 goto err_dealloc_cmap;
2293 } 2149 }
2294 2150
2295 /* set all the vital stuff */
2296 cirrusfb_set_fbinfo(info);
2297
2298 err = register_framebuffer(info); 2151 err = register_framebuffer(info);
2299 if (err < 0) { 2152 if (err < 0) {
2300 printk(KERN_ERR "cirrusfb: could not register " 2153 printk(KERN_ERR "cirrusfb: could not register "
@@ -2307,7 +2160,6 @@ static int cirrusfb_register(struct fb_info *info)
2307 2160
2308err_dealloc_cmap: 2161err_dealloc_cmap:
2309 fb_dealloc_cmap(&info->cmap); 2162 fb_dealloc_cmap(&info->cmap);
2310err_unmap_cirrusfb:
2311 cinfo->unmap(info); 2163 cinfo->unmap(info);
2312 framebuffer_release(info); 2164 framebuffer_release(info);
2313 return err; 2165 return err;
@@ -2330,8 +2182,8 @@ static void __devexit cirrusfb_cleanup(struct fb_info *info)
2330} 2182}
2331 2183
2332#ifdef CONFIG_PCI 2184#ifdef CONFIG_PCI
2333static int cirrusfb_pci_register(struct pci_dev *pdev, 2185static int __devinit cirrusfb_pci_register(struct pci_dev *pdev,
2334 const struct pci_device_id *ent) 2186 const struct pci_device_id *ent)
2335{ 2187{
2336 struct cirrusfb_info *cinfo; 2188 struct cirrusfb_info *cinfo;
2337 struct fb_info *info; 2189 struct fb_info *info;
@@ -2353,7 +2205,6 @@ static int cirrusfb_pci_register(struct pci_dev *pdev,
2353 } 2205 }
2354 2206
2355 cinfo = info->par; 2207 cinfo = info->par;
2356 cinfo->pdev = pdev;
2357 cinfo->btype = btype = (enum cirrus_board) ent->driver_data; 2208 cinfo->btype = btype = (enum cirrus_board) ent->driver_data;
2358 2209
2359 DPRINTK(" Found PCI device, base address 0 is 0x%x, btype set to %d\n", 2210 DPRINTK(" Found PCI device, base address 0 is 0x%x, btype set to %d\n",
@@ -2459,8 +2310,8 @@ static struct pci_driver cirrusfb_pci_driver = {
2459#endif /* CONFIG_PCI */ 2310#endif /* CONFIG_PCI */
2460 2311
2461#ifdef CONFIG_ZORRO 2312#ifdef CONFIG_ZORRO
2462static int cirrusfb_zorro_register(struct zorro_dev *z, 2313static int __devinit cirrusfb_zorro_register(struct zorro_dev *z,
2463 const struct zorro_device_id *ent) 2314 const struct zorro_device_id *ent)
2464{ 2315{
2465 struct cirrusfb_info *cinfo; 2316 struct cirrusfb_info *cinfo;
2466 struct fb_info *info; 2317 struct fb_info *info;
@@ -2489,7 +2340,6 @@ static int cirrusfb_zorro_register(struct zorro_dev *z,
2489 assert(z); 2340 assert(z);
2490 assert(btype != BT_NONE); 2341 assert(btype != BT_NONE);
2491 2342
2492 cinfo->zdev = z;
2493 board_addr = zorro_resource_start(z); 2343 board_addr = zorro_resource_start(z);
2494 board_size = zorro_resource_len(z); 2344 board_size = zorro_resource_len(z);
2495 info->screen_size = size; 2345 info->screen_size = size;
@@ -2621,17 +2471,17 @@ static int __init cirrusfb_setup(char *options) {
2621 return 0; 2471 return 0;
2622 2472
2623 while ((this_opt = strsep(&options, ",")) != NULL) { 2473 while ((this_opt = strsep(&options, ",")) != NULL) {
2624 if (!*this_opt) continue; 2474 if (!*this_opt)
2475 continue;
2625 2476
2626 DPRINTK("cirrusfb_setup: option '%s'\n", this_opt); 2477 DPRINTK("cirrusfb_setup: option '%s'\n", this_opt);
2627 2478
2628 for (i = 0; i < NUM_TOTAL_MODES; i++) {
2629 sprintf(s, "mode:%s", cirrusfb_predefined[i].name);
2630 if (strcmp(this_opt, s) == 0)
2631 cirrusfb_def_mode = i;
2632 }
2633 if (!strcmp(this_opt, "noaccel")) 2479 if (!strcmp(this_opt, "noaccel"))
2634 noaccel = 1; 2480 noaccel = 1;
2481 else if (!strncmp(this_opt, "mode:", 5))
2482 mode_option = this_opt + 5;
2483 else
2484 mode_option = this_opt;
2635 } 2485 }
2636 return 0; 2486 return 0;
2637} 2487}
@@ -2657,6 +2507,11 @@ static void __exit cirrusfb_exit(void)
2657 2507
2658module_init(cirrusfb_init); 2508module_init(cirrusfb_init);
2659 2509
2510module_param(mode_option, charp, 0);
2511MODULE_PARM_DESC(mode_option, "Initial video mode e.g. '648x480-8@60'");
2512module_param(noaccel, bool, 0);
2513MODULE_PARM_DESC(noaccel, "Disable acceleration");
2514
2660#ifdef MODULE 2515#ifdef MODULE
2661module_exit(cirrusfb_exit); 2516module_exit(cirrusfb_exit);
2662#endif 2517#endif
@@ -3050,16 +2905,14 @@ static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
3050 * bestclock() - determine closest possible clock lower(?) than the 2905 * bestclock() - determine closest possible clock lower(?) than the
3051 * desired pixel clock 2906 * desired pixel clock
3052 **************************************************************************/ 2907 **************************************************************************/
3053static void bestclock(long freq, long *best, long *nom, 2908static void bestclock(long freq, int *nom, int *den, int *div)
3054 long *den, long *div, long maxfreq)
3055{ 2909{
3056 long n, h, d, f; 2910 int n, d;
2911 long h, diff;
3057 2912
3058 assert(best != NULL);
3059 assert(nom != NULL); 2913 assert(nom != NULL);
3060 assert(den != NULL); 2914 assert(den != NULL);
3061 assert(div != NULL); 2915 assert(div != NULL);
3062 assert(maxfreq > 0);
3063 2916
3064 *nom = 0; 2917 *nom = 0;
3065 *den = 0; 2918 *den = 0;
@@ -3070,51 +2923,47 @@ static void bestclock(long freq, long *best, long *nom,
3070 if (freq < 8000) 2923 if (freq < 8000)
3071 freq = 8000; 2924 freq = 8000;
3072 2925
3073 if (freq > maxfreq) 2926 diff = freq;
3074 freq = maxfreq;
3075
3076 *best = 0;
3077 f = freq * 10;
3078 2927
3079 for (n = 32; n < 128; n++) { 2928 for (n = 32; n < 128; n++) {
3080 d = (143181 * n) / f; 2929 int s = 0;
2930
2931 d = (14318 * n) / freq;
3081 if ((d >= 7) && (d <= 63)) { 2932 if ((d >= 7) && (d <= 63)) {
3082 if (d > 31) 2933 int temp = d;
3083 d = (d / 2) * 2; 2934
3084 h = (14318 * n) / d; 2935 if (temp > 31) {
3085 if (abs(h - freq) < abs(*best - freq)) { 2936 s = 1;
3086 *best = h; 2937 temp >>= 1;
2938 }
2939 h = ((14318 * n) / temp) >> s;
2940 h = h > freq ? h - freq : freq - h;
2941 if (h < diff) {
2942 diff = h;
3087 *nom = n; 2943 *nom = n;
3088 if (d < 32) { 2944 *den = temp;
3089 *den = d; 2945 *div = s;
3090 *div = 0;
3091 } else {
3092 *den = d / 2;
3093 *div = 1;
3094 }
3095 } 2946 }
3096 } 2947 }
3097 d = DIV_ROUND_UP(143181 * n, f); 2948 d++;
3098 if ((d >= 7) && (d <= 63)) { 2949 if ((d >= 7) && (d <= 63)) {
3099 if (d > 31) 2950 if (d > 31) {
3100 d = (d / 2) * 2; 2951 s = 1;
3101 h = (14318 * n) / d; 2952 d >>= 1;
3102 if (abs(h - freq) < abs(*best - freq)) { 2953 }
3103 *best = h; 2954 h = ((14318 * n) / d) >> s;
2955 h = h > freq ? h - freq : freq - h;
2956 if (h < diff) {
2957 diff = h;
3104 *nom = n; 2958 *nom = n;
3105 if (d < 32) { 2959 *den = d;
3106 *den = d; 2960 *div = s;
3107 *div = 0;
3108 } else {
3109 *den = d / 2;
3110 *div = 1;
3111 }
3112 } 2961 }
3113 } 2962 }
3114 } 2963 }
3115 2964
3116 DPRINTK("Best possible values for given frequency:\n"); 2965 DPRINTK("Best possible values for given frequency:\n");
3117 DPRINTK(" best: %ld kHz nom: %ld den: %ld div: %ld\n", 2966 DPRINTK(" freq: %ld kHz nom: %d den: %d div: %d\n",
3118 freq, *nom, *den, *div); 2967 freq, *nom, *den, *div);
3119 2968
3120 DPRINTK("EXIT\n"); 2969 DPRINTK("EXIT\n");
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 0e0ea4215a30..64b3d30027b8 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -2977,8 +2977,8 @@ static void fbcon_set_all_vcs(struct fb_info *info)
2977 p = &fb_display[vc->vc_num]; 2977 p = &fb_display[vc->vc_num];
2978 set_blitting_type(vc, info); 2978 set_blitting_type(vc, info);
2979 var_to_display(p, &info->var, info); 2979 var_to_display(p, &info->var, info);
2980 cols = FBCON_SWAP(p->rotate, info->var.xres, info->var.yres); 2980 cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
2981 rows = FBCON_SWAP(p->rotate, info->var.yres, info->var.xres); 2981 rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2982 cols /= vc->vc_font.width; 2982 cols /= vc->vc_font.width;
2983 rows /= vc->vc_font.height; 2983 rows /= vc->vc_font.height;
2984 vc_resize(vc, cols, rows); 2984 vc_resize(vc, cols, rows);
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 6df29a62d720..448d209a0bf2 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -239,8 +239,7 @@ static void vgacon_restore_screen(struct vc_data *c)
239 239
240static int vgacon_scrolldelta(struct vc_data *c, int lines) 240static int vgacon_scrolldelta(struct vc_data *c, int lines)
241{ 241{
242 int start, end, count, soff, diff; 242 int start, end, count, soff;
243 void *d, *s;
244 243
245 if (!lines) { 244 if (!lines) {
246 c->vc_visible_origin = c->vc_origin; 245 c->vc_visible_origin = c->vc_origin;
@@ -287,29 +286,29 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines)
287 if (count > c->vc_rows) 286 if (count > c->vc_rows)
288 count = c->vc_rows; 287 count = c->vc_rows;
289 288
290 diff = c->vc_rows - count; 289 if (count) {
290 int copysize;
291 291
292 d = (void *) c->vc_origin; 292 int diff = c->vc_rows - count;
293 s = (void *) c->vc_screenbuf; 293 void *d = (void *) c->vc_origin;
294 void *s = (void *) c->vc_screenbuf;
294 295
295 while (count--) { 296 count *= c->vc_size_row;
296 scr_memcpyw(d, vgacon_scrollback + soff, c->vc_size_row); 297 /* how much memory to end of buffer left? */
297 d += c->vc_size_row; 298 copysize = min(count, vgacon_scrollback_size - soff);
298 soff += c->vc_size_row; 299 scr_memcpyw(d, vgacon_scrollback + soff, copysize);
300 d += copysize;
301 count -= copysize;
299 302
300 if (soff >= vgacon_scrollback_size) 303 if (count) {
301 soff = 0; 304 scr_memcpyw(d, vgacon_scrollback, count);
302 } 305 d += count;
306 }
303 307
304 if (diff == c->vc_rows) { 308 if (diff)
309 scr_memcpyw(d, s, diff * c->vc_size_row);
310 } else
305 vgacon_cursor(c, CM_MOVE); 311 vgacon_cursor(c, CM_MOVE);
306 } else {
307 while (diff--) {
308 scr_memcpyw(d, s, c->vc_size_row);
309 d += c->vc_size_row;
310 s += c->vc_size_row;
311 }
312 }
313 312
314 return 1; 313 return 1;
315} 314}
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c
index bd779ae44b1e..daf9b81878a4 100644
--- a/drivers/video/efifb.c
+++ b/drivers/video/efifb.c
@@ -12,6 +12,7 @@
12#include <linux/fb.h> 12#include <linux/fb.h>
13#include <linux/platform_device.h> 13#include <linux/platform_device.h>
14#include <linux/screen_info.h> 14#include <linux/screen_info.h>
15#include <linux/dmi.h>
15 16
16#include <video/vga.h> 17#include <video/vga.h>
17 18
@@ -33,6 +34,105 @@ static struct fb_fix_screeninfo efifb_fix __initdata = {
33 .visual = FB_VISUAL_TRUECOLOR, 34 .visual = FB_VISUAL_TRUECOLOR,
34}; 35};
35 36
37enum {
38 M_I17, /* 17-Inch iMac */
39 M_I20, /* 20-Inch iMac */
40 M_I20_SR, /* 20-Inch iMac (Santa Rosa) */
41 M_I24, /* 24-Inch iMac */
42 M_MINI, /* Mac Mini */
43 M_MB, /* MacBook */
44 M_MB_2, /* MacBook, 2nd rev. */
45 M_MB_3, /* MacBook, 3rd rev. */
46 M_MB_SR, /* MacBook, 2nd gen, (Santa Rosa) */
47 M_MBA, /* MacBook Air */
48 M_MBP, /* MacBook Pro */
49 M_MBP_2, /* MacBook Pro 2nd gen */
50 M_MBP_SR, /* MacBook Pro (Santa Rosa) */
51 M_MBP_4, /* MacBook Pro, 4th gen */
52 M_UNKNOWN /* placeholder */
53};
54
55static struct efifb_dmi_info {
56 char *optname;
57 unsigned long base;
58 int stride;
59 int width;
60 int height;
61} dmi_list[] = {
62 [M_I17] = { "i17", 0x80010000, 1472 * 4, 1440, 900 },
63 [M_I20] = { "i20", 0x80010000, 1728 * 4, 1680, 1050 }, /* guess */
64 [M_I20_SR] = { "imac7", 0x40010000, 1728 * 4, 1680, 1050 },
65 [M_I24] = { "i24", 0x80010000, 2048 * 4, 1920, 1200 }, /* guess */
66 [M_MINI]= { "mini", 0x80000000, 2048 * 4, 1024, 768 },
67 [M_MB] = { "macbook", 0x80000000, 2048 * 4, 1280, 800 },
68 [M_MBA] = { "mba", 0x80000000, 2048 * 4, 1280, 800 },
69 [M_MBP] = { "mbp", 0x80010000, 1472 * 4, 1440, 900 },
70 [M_MBP_2] = { "mbp2", 0, 0, 0, 0 }, /* placeholder */
71 [M_MBP_SR] = { "mbp3", 0x80030000, 2048 * 4, 1440, 900 },
72 [M_MBP_4] = { "mbp4", 0xc0060000, 2048 * 4, 1920, 1200 },
73 [M_UNKNOWN] = { NULL, 0, 0, 0, 0 }
74};
75
76static int set_system(const struct dmi_system_id *id);
77
78#define EFIFB_DMI_SYSTEM_ID(vendor, name, enumid) \
79 { set_system, name, { \
80 DMI_MATCH(DMI_BIOS_VENDOR, vendor), \
81 DMI_MATCH(DMI_PRODUCT_NAME, name) }, \
82 &dmi_list[enumid] }
83
84static struct dmi_system_id __initdata dmi_system_table[] = {
85 EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac4,1", M_I17),
86 /* At least one of these two will be right; maybe both? */
87 EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac5,1", M_I20),
88 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac5,1", M_I20),
89 /* At least one of these two will be right; maybe both? */
90 EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac6,1", M_I24),
91 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac6,1", M_I24),
92 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac7,1", M_I20_SR),
93 EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "Macmini1,1", M_MINI),
94 EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook1,1", M_MB),
95 /* At least one of these two will be right; maybe both? */
96 EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook2,1", M_MB),
97 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook2,1", M_MB),
98 /* At least one of these two will be right; maybe both? */
99 EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook3,1", M_MB),
100 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook3,1", M_MB),
101 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook4,1", M_MB),
102 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir1,1", M_MBA),
103 EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro1,1", M_MBP),
104 EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,1", M_MBP_2),
105 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro2,1", M_MBP_2),
106 EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro3,1", M_MBP_SR),
107 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro3,1", M_MBP_SR),
108 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro4,1", M_MBP_4),
109 {},
110};
111
112static int set_system(const struct dmi_system_id *id)
113{
114 struct efifb_dmi_info *info = id->driver_data;
115 if (info->base == 0)
116 return -ENODEV;
117
118 printk(KERN_INFO "efifb: dmi detected %s - framebuffer at %p "
119 "(%dx%d, stride %d)\n", id->ident,
120 (void *)info->base, info->width, info->height,
121 info->stride);
122
123 /* Trust the bootloader over the DMI tables */
124 if (screen_info.lfb_base == 0)
125 screen_info.lfb_base = info->base;
126 if (screen_info.lfb_linelength == 0)
127 screen_info.lfb_linelength = info->stride;
128 if (screen_info.lfb_width == 0)
129 screen_info.lfb_width = info->width;
130 if (screen_info.lfb_height == 0)
131 screen_info.lfb_height = info->height;
132
133 return 0;
134}
135
36static int efifb_setcolreg(unsigned regno, unsigned red, unsigned green, 136static int efifb_setcolreg(unsigned regno, unsigned red, unsigned green,
37 unsigned blue, unsigned transp, 137 unsigned blue, unsigned transp,
38 struct fb_info *info) 138 struct fb_info *info)
@@ -67,6 +167,38 @@ static struct fb_ops efifb_ops = {
67 .fb_imageblit = cfb_imageblit, 167 .fb_imageblit = cfb_imageblit,
68}; 168};
69 169
170static int __init efifb_setup(char *options)
171{
172 char *this_opt;
173 int i;
174
175 if (!options || !*options)
176 return 0;
177
178 while ((this_opt = strsep(&options, ",")) != NULL) {
179 if (!*this_opt) continue;
180
181 for (i = 0; i < M_UNKNOWN; i++) {
182 if (!strcmp(this_opt, dmi_list[i].optname) &&
183 dmi_list[i].base != 0) {
184 screen_info.lfb_base = dmi_list[i].base;
185 screen_info.lfb_linelength = dmi_list[i].stride;
186 screen_info.lfb_width = dmi_list[i].width;
187 screen_info.lfb_height = dmi_list[i].height;
188 }
189 }
190 if (!strncmp(this_opt, "base:", 5))
191 screen_info.lfb_base = simple_strtoul(this_opt+5, NULL, 0);
192 else if (!strncmp(this_opt, "stride:", 7))
193 screen_info.lfb_linelength = simple_strtoul(this_opt+7, NULL, 0) * 4;
194 else if (!strncmp(this_opt, "height:", 7))
195 screen_info.lfb_height = simple_strtoul(this_opt+7, NULL, 0);
196 else if (!strncmp(this_opt, "width:", 6))
197 screen_info.lfb_width = simple_strtoul(this_opt+6, NULL, 0);
198 }
199 return 0;
200}
201
70static int __init efifb_probe(struct platform_device *dev) 202static int __init efifb_probe(struct platform_device *dev)
71{ 203{
72 struct fb_info *info; 204 struct fb_info *info;
@@ -74,6 +206,26 @@ static int __init efifb_probe(struct platform_device *dev)
74 unsigned int size_vmode; 206 unsigned int size_vmode;
75 unsigned int size_remap; 207 unsigned int size_remap;
76 unsigned int size_total; 208 unsigned int size_total;
209 int request_succeeded = 0;
210
211 printk(KERN_INFO "efifb: probing for efifb\n");
212
213 if (!screen_info.lfb_depth)
214 screen_info.lfb_depth = 32;
215 if (!screen_info.pages)
216 screen_info.pages = 1;
217
218 /* just assume they're all unset if any are */
219 if (!screen_info.blue_size) {
220 screen_info.blue_size = 8;
221 screen_info.blue_pos = 0;
222 screen_info.green_size = 8;
223 screen_info.green_pos = 8;
224 screen_info.red_size = 8;
225 screen_info.red_pos = 16;
226 screen_info.rsvd_size = 8;
227 screen_info.rsvd_pos = 24;
228 }
77 229
78 efifb_fix.smem_start = screen_info.lfb_base; 230 efifb_fix.smem_start = screen_info.lfb_base;
79 efifb_defined.bits_per_pixel = screen_info.lfb_depth; 231 efifb_defined.bits_per_pixel = screen_info.lfb_depth;
@@ -98,21 +250,25 @@ static int __init efifb_probe(struct platform_device *dev)
98 * option to simply use size_total as that 250 * option to simply use size_total as that
99 * wastes plenty of kernel address space. */ 251 * wastes plenty of kernel address space. */
100 size_remap = size_vmode * 2; 252 size_remap = size_vmode * 2;
101 if (size_remap < size_vmode)
102 size_remap = size_vmode;
103 if (size_remap > size_total) 253 if (size_remap > size_total)
104 size_remap = size_total; 254 size_remap = size_total;
255 if (size_remap % PAGE_SIZE)
256 size_remap += PAGE_SIZE - (size_remap % PAGE_SIZE);
105 efifb_fix.smem_len = size_remap; 257 efifb_fix.smem_len = size_remap;
106 258
107 if (!request_mem_region(efifb_fix.smem_start, size_total, "efifb")) 259 if (request_mem_region(efifb_fix.smem_start, size_remap, "efifb")) {
260 request_succeeded = 1;
261 } else {
108 /* We cannot make this fatal. Sometimes this comes from magic 262 /* We cannot make this fatal. Sometimes this comes from magic
109 spaces our resource handlers simply don't know about */ 263 spaces our resource handlers simply don't know about */
110 printk(KERN_WARNING 264 printk(KERN_WARNING
111 "efifb: cannot reserve video memory at 0x%lx\n", 265 "efifb: cannot reserve video memory at 0x%lx\n",
112 efifb_fix.smem_start); 266 efifb_fix.smem_start);
267 }
113 268
114 info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev); 269 info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);
115 if (!info) { 270 if (!info) {
271 printk(KERN_ERR "efifb: cannot allocate framebuffer\n");
116 err = -ENOMEM; 272 err = -ENOMEM;
117 goto err_release_mem; 273 goto err_release_mem;
118 } 274 }
@@ -125,7 +281,7 @@ static int __init efifb_probe(struct platform_device *dev)
125 "0x%x @ 0x%lx\n", 281 "0x%x @ 0x%lx\n",
126 efifb_fix.smem_len, efifb_fix.smem_start); 282 efifb_fix.smem_len, efifb_fix.smem_start);
127 err = -EIO; 283 err = -EIO;
128 goto err_unmap; 284 goto err_release_fb;
129 } 285 }
130 286
131 printk(KERN_INFO "efifb: framebuffer at 0x%lx, mapped to 0x%p, " 287 printk(KERN_INFO "efifb: framebuffer at 0x%lx, mapped to 0x%p, "
@@ -178,25 +334,27 @@ static int __init efifb_probe(struct platform_device *dev)
178 info->fix = efifb_fix; 334 info->fix = efifb_fix;
179 info->flags = FBINFO_FLAG_DEFAULT; 335 info->flags = FBINFO_FLAG_DEFAULT;
180 336
181 if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { 337 if ((err = fb_alloc_cmap(&info->cmap, 256, 0)) < 0) {
182 err = -ENOMEM; 338 printk(KERN_ERR "efifb: cannot allocate colormap\n");
183 goto err_unmap; 339 goto err_unmap;
184 } 340 }
185 if (register_framebuffer(info) < 0) { 341 if ((err = register_framebuffer(info)) < 0) {
186 err = -EINVAL; 342 printk(KERN_ERR "efifb: cannot register framebuffer\n");
187 goto err_fb_dealoc; 343 goto err_fb_dealoc;
188 } 344 }
189 printk(KERN_INFO "fb%d: %s frame buffer device\n", 345 printk(KERN_INFO "fb%d: %s frame buffer device\n",
190 info->node, info->fix.id); 346 info->node, info->fix.id);
191 return 0; 347 return 0;
192 348
193err_fb_dealoc: 349err_fb_dealoc:
194 fb_dealloc_cmap(&info->cmap); 350 fb_dealloc_cmap(&info->cmap);
195err_unmap: 351err_unmap:
196 iounmap(info->screen_base); 352 iounmap(info->screen_base);
353err_release_fb:
197 framebuffer_release(info); 354 framebuffer_release(info);
198err_release_mem: 355err_release_mem:
199 release_mem_region(efifb_fix.smem_start, size_total); 356 if (request_succeeded)
357 release_mem_region(efifb_fix.smem_start, size_total);
200 return err; 358 return err;
201} 359}
202 360
@@ -214,9 +372,22 @@ static struct platform_device efifb_device = {
214static int __init efifb_init(void) 372static int __init efifb_init(void)
215{ 373{
216 int ret; 374 int ret;
375 char *option = NULL;
217 376
218 if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) 377 if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI)
219 return -ENODEV; 378 return -ENODEV;
379 dmi_check_system(dmi_system_table);
380
381 if (fb_get_options("efifb", &option))
382 return -ENODEV;
383 efifb_setup(option);
384
385 /* We don't get linelength from UGA Draw Protocol, only from
386 * EFI Graphics Protocol. So if it's not in DMI, and it's not
387 * passed in from the user, we really can't use the framebuffer.
388 */
389 if (!screen_info.lfb_linelength)
390 return -ENODEV;
220 391
221 ret = platform_driver_register(&efifb_driver); 392 ret = platform_driver_register(&efifb_driver);
222 393
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 61b36ca06997..217c5118ae9e 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -28,9 +28,7 @@
28#include <linux/proc_fs.h> 28#include <linux/proc_fs.h>
29#include <linux/seq_file.h> 29#include <linux/seq_file.h>
30#include <linux/console.h> 30#include <linux/console.h>
31#ifdef CONFIG_KMOD
32#include <linux/kmod.h> 31#include <linux/kmod.h>
33#endif
34#include <linux/err.h> 32#include <linux/err.h>
35#include <linux/device.h> 33#include <linux/device.h>
36#include <linux/efi.h> 34#include <linux/efi.h>
@@ -837,13 +835,6 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
837 return (cnt) ? cnt : err; 835 return (cnt) ? cnt : err;
838} 836}
839 837
840#ifdef CONFIG_KMOD
841static void try_to_load(int fb)
842{
843 request_module("fb%d", fb);
844}
845#endif /* CONFIG_KMOD */
846
847int 838int
848fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var) 839fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var)
849{ 840{
@@ -1086,10 +1077,8 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
1086 return -EINVAL; 1077 return -EINVAL;
1087 if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX) 1078 if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
1088 return -EINVAL; 1079 return -EINVAL;
1089#ifdef CONFIG_KMOD
1090 if (!registered_fb[con2fb.framebuffer]) 1080 if (!registered_fb[con2fb.framebuffer])
1091 try_to_load(con2fb.framebuffer); 1081 request_module("fb%d", con2fb.framebuffer);
1092#endif /* CONFIG_KMOD */
1093 if (!registered_fb[con2fb.framebuffer]) 1082 if (!registered_fb[con2fb.framebuffer])
1094 return -EINVAL; 1083 return -EINVAL;
1095 event.info = info; 1084 event.info = info;
@@ -1327,10 +1316,8 @@ fb_open(struct inode *inode, struct file *file)
1327 if (fbidx >= FB_MAX) 1316 if (fbidx >= FB_MAX)
1328 return -ENODEV; 1317 return -ENODEV;
1329 lock_kernel(); 1318 lock_kernel();
1330#ifdef CONFIG_KMOD
1331 if (!(info = registered_fb[fbidx])) 1319 if (!(info = registered_fb[fbidx]))
1332 try_to_load(fbidx); 1320 request_module("fb%d", fbidx);
1333#endif /* CONFIG_KMOD */
1334 if (!(info = registered_fb[fbidx])) { 1321 if (!(info = registered_fb[fbidx])) {
1335 res = -ENODEV; 1322 res = -ENODEV;
1336 goto out; 1323 goto out;
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index 6a0aa180c266..5c1a2c01778f 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -564,7 +564,13 @@ static void get_detailed_timing(unsigned char *block,
564 mode->sync |= FB_SYNC_VERT_HIGH_ACT; 564 mode->sync |= FB_SYNC_VERT_HIGH_ACT;
565 mode->refresh = PIXEL_CLOCK/((H_ACTIVE + H_BLANKING) * 565 mode->refresh = PIXEL_CLOCK/((H_ACTIVE + H_BLANKING) *
566 (V_ACTIVE + V_BLANKING)); 566 (V_ACTIVE + V_BLANKING));
567 mode->vmode = 0; 567 if (INTERLACED) {
568 mode->yres *= 2;
569 mode->upper_margin *= 2;
570 mode->lower_margin *= 2;
571 mode->vsync_len *= 2;
572 mode->vmode |= FB_VMODE_INTERLACED;
573 }
568 mode->flag = FB_MODE_IS_DETAILED; 574 mode->flag = FB_MODE_IS_DETAILED;
569 575
570 DPRINTK(" %d MHz ", PIXEL_CLOCK/1000000); 576 DPRINTK(" %d MHz ", PIXEL_CLOCK/1000000);
diff --git a/drivers/video/imacfb.c b/drivers/video/imacfb.c
index 9366ef2bb5f7..e69de29bb2d1 100644
--- a/drivers/video/imacfb.c
+++ b/drivers/video/imacfb.c
@@ -1,376 +0,0 @@
1/*
2 * framebuffer driver for Intel Based Mac's
3 *
4 * (c) 2006 Edgar Hucek <gimli@dark-green.com>
5 * Original imac driver written by Gerd Knorr <kraxel@goldbach.in-berlin.de>
6 *
7 */
8
9#include <linux/delay.h>
10#include <linux/errno.h>
11#include <linux/fb.h>
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/ioport.h>
15#include <linux/mm.h>
16#include <linux/module.h>
17#include <linux/platform_device.h>
18#include <linux/screen_info.h>
19#include <linux/slab.h>
20#include <linux/string.h>
21#include <linux/dmi.h>
22#include <linux/efi.h>
23
24#include <asm/io.h>
25
26#include <video/vga.h>
27
28typedef enum _MAC_TYPE {
29 M_I17,
30 M_I20,
31 M_MINI,
32 M_MACBOOK,
33 M_UNKNOWN
34} MAC_TYPE;
35
36/* --------------------------------------------------------------------- */
37
38static struct fb_var_screeninfo imacfb_defined __initdata = {
39 .activate = FB_ACTIVATE_NOW,
40 .height = -1,
41 .width = -1,
42 .right_margin = 32,
43 .upper_margin = 16,
44 .lower_margin = 4,
45 .vsync_len = 4,
46 .vmode = FB_VMODE_NONINTERLACED,
47};
48
49static struct fb_fix_screeninfo imacfb_fix __initdata = {
50 .id = "IMAC VGA",
51 .type = FB_TYPE_PACKED_PIXELS,
52 .accel = FB_ACCEL_NONE,
53 .visual = FB_VISUAL_TRUECOLOR,
54};
55
56static int inverse;
57static int model = M_UNKNOWN;
58static int manual_height;
59static int manual_width;
60
61static int set_system(const struct dmi_system_id *id)
62{
63 printk(KERN_INFO "imacfb: %s detected - set system to %ld\n",
64 id->ident, (long)id->driver_data);
65
66 model = (long)id->driver_data;
67
68 return 0;
69}
70
71static struct dmi_system_id __initdata dmi_system_table[] = {
72 { set_system, "iMac4,1", {
73 DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."),
74 DMI_MATCH(DMI_PRODUCT_NAME,"iMac4,1") }, (void*)M_I17},
75 { set_system, "MacBookPro1,1", {
76 DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."),
77 DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro1,1") }, (void*)M_I17},
78 { set_system, "MacBook1,1", {
79 DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."),
80 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook1,1")}, (void *)M_MACBOOK},
81 { set_system, "Macmini1,1", {
82 DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."),
83 DMI_MATCH(DMI_PRODUCT_NAME,"Macmini1,1")}, (void *)M_MINI},
84 {},
85};
86
87#define DEFAULT_FB_MEM 1024*1024*16
88
89/* --------------------------------------------------------------------- */
90
91static int imacfb_setcolreg(unsigned regno, unsigned red, unsigned green,
92 unsigned blue, unsigned transp,
93 struct fb_info *info)
94{
95 /*
96 * Set a single color register. The values supplied are
97 * already rounded down to the hardware's capabilities
98 * (according to the entries in the `var' structure). Return
99 * != 0 for invalid regno.
100 */
101
102 if (regno >= info->cmap.len)
103 return 1;
104
105 if (regno < 16) {
106 red >>= 8;
107 green >>= 8;
108 blue >>= 8;
109 ((u32 *)(info->pseudo_palette))[regno] =
110 (red << info->var.red.offset) |
111 (green << info->var.green.offset) |
112 (blue << info->var.blue.offset);
113 }
114 return 0;
115}
116
117static struct fb_ops imacfb_ops = {
118 .owner = THIS_MODULE,
119 .fb_setcolreg = imacfb_setcolreg,
120 .fb_fillrect = cfb_fillrect,
121 .fb_copyarea = cfb_copyarea,
122 .fb_imageblit = cfb_imageblit,
123};
124
125static int __init imacfb_setup(char *options)
126{
127 char *this_opt;
128
129 if (!options || !*options)
130 return 0;
131
132 while ((this_opt = strsep(&options, ",")) != NULL) {
133 if (!*this_opt) continue;
134
135 if (!strcmp(this_opt, "inverse"))
136 inverse = 1;
137 else if (!strcmp(this_opt, "i17"))
138 model = M_I17;
139 else if (!strcmp(this_opt, "i20"))
140 model = M_I20;
141 else if (!strcmp(this_opt, "mini"))
142 model = M_MINI;
143 else if (!strcmp(this_opt, "macbook"))
144 model = M_MACBOOK;
145 else if (!strncmp(this_opt, "height:", 7))
146 manual_height = simple_strtoul(this_opt+7, NULL, 0);
147 else if (!strncmp(this_opt, "width:", 6))
148 manual_width = simple_strtoul(this_opt+6, NULL, 0);
149 }
150 return 0;
151}
152
153static int __init imacfb_probe(struct platform_device *dev)
154{
155 struct fb_info *info;
156 int err;
157 unsigned int size_vmode;
158 unsigned int size_remap;
159 unsigned int size_total;
160
161 screen_info.lfb_depth = 32;
162 screen_info.lfb_size = DEFAULT_FB_MEM / 0x10000;
163 screen_info.pages=1;
164 screen_info.blue_size = 8;
165 screen_info.blue_pos = 0;
166 screen_info.green_size = 8;
167 screen_info.green_pos = 8;
168 screen_info.red_size = 8;
169 screen_info.red_pos = 16;
170 screen_info.rsvd_size = 8;
171 screen_info.rsvd_pos = 24;
172
173 switch (model) {
174 case M_I17:
175 screen_info.lfb_width = 1440;
176 screen_info.lfb_height = 900;
177 screen_info.lfb_linelength = 1472 * 4;
178 screen_info.lfb_base = 0x80010000;
179 break;
180 case M_I20:
181 screen_info.lfb_width = 1680;
182 screen_info.lfb_height = 1050;
183 screen_info.lfb_linelength = 1728 * 4;
184 screen_info.lfb_base = 0x80010000;
185 break;
186 case M_MINI:
187 screen_info.lfb_width = 1024;
188 screen_info.lfb_height = 768;
189 screen_info.lfb_linelength = 2048 * 4;
190 screen_info.lfb_base = 0x80000000;
191 break;
192 case M_MACBOOK:
193 screen_info.lfb_width = 1280;
194 screen_info.lfb_height = 800;
195 screen_info.lfb_linelength = 2048 * 4;
196 screen_info.lfb_base = 0x80000000;
197 break;
198 }
199
200 /* if the user wants to manually specify height/width,
201 we will override the defaults */
202 /* TODO: eventually get auto-detection working */
203 if (manual_height > 0)
204 screen_info.lfb_height = manual_height;
205 if (manual_width > 0)
206 screen_info.lfb_width = manual_width;
207
208 imacfb_fix.smem_start = screen_info.lfb_base;
209 imacfb_defined.bits_per_pixel = screen_info.lfb_depth;
210 imacfb_defined.xres = screen_info.lfb_width;
211 imacfb_defined.yres = screen_info.lfb_height;
212 imacfb_fix.line_length = screen_info.lfb_linelength;
213
214 /* size_vmode -- that is the amount of memory needed for the
215 * used video mode, i.e. the minimum amount of
216 * memory we need. */
217 size_vmode = imacfb_defined.yres * imacfb_fix.line_length;
218
219 /* size_total -- all video memory we have. Used for
220 * entries, ressource allocation and bounds
221 * checking. */
222 size_total = screen_info.lfb_size * 65536;
223 if (size_total < size_vmode)
224 size_total = size_vmode;
225
226 /* size_remap -- the amount of video memory we are going to
227 * use for imacfb. With modern cards it is no
228 * option to simply use size_total as that
229 * wastes plenty of kernel address space. */
230 size_remap = size_vmode * 2;
231 if (size_remap < size_vmode)
232 size_remap = size_vmode;
233 if (size_remap > size_total)
234 size_remap = size_total;
235 imacfb_fix.smem_len = size_remap;
236
237 if (!request_mem_region(imacfb_fix.smem_start, size_total, "imacfb")) {
238 printk(KERN_WARNING
239 "imacfb: cannot reserve video memory at 0x%lx\n",
240 imacfb_fix.smem_start);
241 /* We cannot make this fatal. Sometimes this comes from magic
242 spaces our resource handlers simply don't know about */
243 }
244
245 info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);
246 if (!info) {
247 err = -ENOMEM;
248 goto err_release_mem;
249 }
250 info->pseudo_palette = info->par;
251 info->par = NULL;
252
253 info->screen_base = ioremap(imacfb_fix.smem_start, imacfb_fix.smem_len);
254 if (!info->screen_base) {
255 printk(KERN_ERR "imacfb: abort, cannot ioremap video memory "
256 "0x%x @ 0x%lx\n",
257 imacfb_fix.smem_len, imacfb_fix.smem_start);
258 err = -EIO;
259 goto err_unmap;
260 }
261
262 printk(KERN_INFO "imacfb: framebuffer at 0x%lx, mapped to 0x%p, "
263 "using %dk, total %dk\n",
264 imacfb_fix.smem_start, info->screen_base,
265 size_remap/1024, size_total/1024);
266 printk(KERN_INFO "imacfb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
267 imacfb_defined.xres, imacfb_defined.yres,
268 imacfb_defined.bits_per_pixel, imacfb_fix.line_length,
269 screen_info.pages);
270
271 imacfb_defined.xres_virtual = imacfb_defined.xres;
272 imacfb_defined.yres_virtual = imacfb_fix.smem_len /
273 imacfb_fix.line_length;
274 printk(KERN_INFO "imacfb: scrolling: redraw\n");
275 imacfb_defined.yres_virtual = imacfb_defined.yres;
276
277 /* some dummy values for timing to make fbset happy */
278 imacfb_defined.pixclock = 10000000 / imacfb_defined.xres *
279 1000 / imacfb_defined.yres;
280 imacfb_defined.left_margin = (imacfb_defined.xres / 8) & 0xf8;
281 imacfb_defined.hsync_len = (imacfb_defined.xres / 8) & 0xf8;
282
283 imacfb_defined.red.offset = screen_info.red_pos;
284 imacfb_defined.red.length = screen_info.red_size;
285 imacfb_defined.green.offset = screen_info.green_pos;
286 imacfb_defined.green.length = screen_info.green_size;
287 imacfb_defined.blue.offset = screen_info.blue_pos;
288 imacfb_defined.blue.length = screen_info.blue_size;
289 imacfb_defined.transp.offset = screen_info.rsvd_pos;
290 imacfb_defined.transp.length = screen_info.rsvd_size;
291
292 printk(KERN_INFO "imacfb: %s: "
293 "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n",
294 "Truecolor",
295 screen_info.rsvd_size,
296 screen_info.red_size,
297 screen_info.green_size,
298 screen_info.blue_size,
299 screen_info.rsvd_pos,
300 screen_info.red_pos,
301 screen_info.green_pos,
302 screen_info.blue_pos);
303
304 imacfb_fix.ypanstep = 0;
305 imacfb_fix.ywrapstep = 0;
306
307 /* request failure does not faze us, as vgacon probably has this
308 * region already (FIXME) */
309 request_region(0x3c0, 32, "imacfb");
310
311 info->fbops = &imacfb_ops;
312 info->var = imacfb_defined;
313 info->fix = imacfb_fix;
314 info->flags = FBINFO_FLAG_DEFAULT;
315
316 if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
317 err = -ENOMEM;
318 goto err_unmap;
319 }
320 if (register_framebuffer(info)<0) {
321 err = -EINVAL;
322 goto err_fb_dealoc;
323 }
324 printk(KERN_INFO "fb%d: %s frame buffer device\n",
325 info->node, info->fix.id);
326 return 0;
327
328err_fb_dealoc:
329 fb_dealloc_cmap(&info->cmap);
330err_unmap:
331 iounmap(info->screen_base);
332 framebuffer_release(info);
333err_release_mem:
334 release_mem_region(imacfb_fix.smem_start, size_total);
335 return err;
336}
337
338static struct platform_driver imacfb_driver = {
339 .probe = imacfb_probe,
340 .driver = {
341 .name = "imacfb",
342 },
343};
344
345static struct platform_device imacfb_device = {
346 .name = "imacfb",
347};
348
349static int __init imacfb_init(void)
350{
351 int ret;
352 char *option = NULL;
353
354 if (!efi_enabled)
355 return -ENODEV;
356 if (!dmi_check_system(dmi_system_table))
357 return -ENODEV;
358 if (model == M_UNKNOWN)
359 return -ENODEV;
360
361 if (fb_get_options("imacfb", &option))
362 return -ENODEV;
363
364 imacfb_setup(option);
365 ret = platform_driver_register(&imacfb_driver);
366
367 if (!ret) {
368 ret = platform_device_register(&imacfb_device);
369 if (ret)
370 platform_driver_unregister(&imacfb_driver);
371 }
372 return ret;
373}
374module_init(imacfb_init);
375
376MODULE_LICENSE("GPL");
diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/intelfb/intelfb.h
index 3325fbd68ab3..a50bea614804 100644
--- a/drivers/video/intelfb/intelfb.h
+++ b/drivers/video/intelfb/intelfb.h
@@ -12,9 +12,9 @@
12#endif 12#endif
13 13
14/*** Version/name ***/ 14/*** Version/name ***/
15#define INTELFB_VERSION "0.9.5" 15#define INTELFB_VERSION "0.9.6"
16#define INTELFB_MODULE_NAME "intelfb" 16#define INTELFB_MODULE_NAME "intelfb"
17#define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM" 17#define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/945GME/965G/965GM"
18 18
19 19
20/*** Debug/feature defines ***/ 20/*** Debug/feature defines ***/
@@ -58,6 +58,7 @@
58#define PCI_DEVICE_ID_INTEL_915GM 0x2592 58#define PCI_DEVICE_ID_INTEL_915GM 0x2592
59#define PCI_DEVICE_ID_INTEL_945G 0x2772 59#define PCI_DEVICE_ID_INTEL_945G 0x2772
60#define PCI_DEVICE_ID_INTEL_945GM 0x27A2 60#define PCI_DEVICE_ID_INTEL_945GM 0x27A2
61#define PCI_DEVICE_ID_INTEL_945GME 0x27AE
61#define PCI_DEVICE_ID_INTEL_965G 0x29A2 62#define PCI_DEVICE_ID_INTEL_965G 0x29A2
62#define PCI_DEVICE_ID_INTEL_965GM 0x2A02 63#define PCI_DEVICE_ID_INTEL_965GM 0x2A02
63 64
@@ -160,6 +161,7 @@ enum intel_chips {
160 INTEL_915GM, 161 INTEL_915GM,
161 INTEL_945G, 162 INTEL_945G,
162 INTEL_945GM, 163 INTEL_945GM,
164 INTEL_945GME,
163 INTEL_965G, 165 INTEL_965G,
164 INTEL_965GM, 166 INTEL_965GM,
165}; 167};
@@ -363,6 +365,7 @@ struct intelfb_info {
363 ((dinfo)->chipset == INTEL_915GM) || \ 365 ((dinfo)->chipset == INTEL_915GM) || \
364 ((dinfo)->chipset == INTEL_945G) || \ 366 ((dinfo)->chipset == INTEL_945G) || \
365 ((dinfo)->chipset == INTEL_945GM) || \ 367 ((dinfo)->chipset == INTEL_945GM) || \
368 ((dinfo)->chipset == INTEL_945GME) || \
366 ((dinfo)->chipset == INTEL_965G) || \ 369 ((dinfo)->chipset == INTEL_965G) || \
367 ((dinfo)->chipset == INTEL_965GM)) 370 ((dinfo)->chipset == INTEL_965GM))
368 371
diff --git a/drivers/video/intelfb/intelfb_i2c.c b/drivers/video/intelfb/intelfb_i2c.c
index fcf9fadbf572..5d896b81f4e0 100644
--- a/drivers/video/intelfb/intelfb_i2c.c
+++ b/drivers/video/intelfb/intelfb_i2c.c
@@ -171,6 +171,7 @@ void intelfb_create_i2c_busses(struct intelfb_info *dinfo)
171 /* has some LVDS + tv-out */ 171 /* has some LVDS + tv-out */
172 case INTEL_945G: 172 case INTEL_945G:
173 case INTEL_945GM: 173 case INTEL_945GM:
174 case INTEL_945GME:
174 case INTEL_965G: 175 case INTEL_965G:
175 case INTEL_965GM: 176 case INTEL_965GM:
176 /* SDVO ports have a single control bus - 2 devices */ 177 /* SDVO ports have a single control bus - 2 devices */
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index e44303f9bc52..a09e23649357 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -2,7 +2,7 @@
2 * intelfb 2 * intelfb
3 * 3 *
4 * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G/915GM/ 4 * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G/915GM/
5 * 945G/945GM/965G/965GM integrated graphics chips. 5 * 945G/945GM/945GME/965G/965GM integrated graphics chips.
6 * 6 *
7 * Copyright © 2002, 2003 David Dawes <dawes@xfree86.org> 7 * Copyright © 2002, 2003 David Dawes <dawes@xfree86.org>
8 * 2004 Sylvain Meyer 8 * 2004 Sylvain Meyer
@@ -102,6 +102,9 @@
102 * 102 *
103 * 04/2008 - Version 0.9.5 103 * 04/2008 - Version 0.9.5
104 * Add support for 965G/965GM. (Maik Broemme <mbroemme@plusserver.de>) 104 * Add support for 965G/965GM. (Maik Broemme <mbroemme@plusserver.de>)
105 *
106 * 08/2008 - Version 0.9.6
107 * Add support for 945GME. (Phil Endecott <spam_from_intelfb@chezphil.org>)
105 */ 108 */
106 109
107#include <linux/module.h> 110#include <linux/module.h>
@@ -183,6 +186,7 @@ static struct pci_device_id intelfb_pci_table[] __devinitdata = {
183 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915GM }, 186 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915GM },
184 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945G }, 187 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945G },
185 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945GM }, 188 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945GM },
189 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945GME, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945GME },
186 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_965G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_965G }, 190 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_965G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_965G },
187 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_965GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_965GM }, 191 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_965GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_965GM },
188 { 0, } 192 { 0, }
@@ -555,6 +559,7 @@ static int __devinit intelfb_pci_register(struct pci_dev *pdev,
555 (ent->device == PCI_DEVICE_ID_INTEL_915GM) || 559 (ent->device == PCI_DEVICE_ID_INTEL_915GM) ||
556 (ent->device == PCI_DEVICE_ID_INTEL_945G) || 560 (ent->device == PCI_DEVICE_ID_INTEL_945G) ||
557 (ent->device == PCI_DEVICE_ID_INTEL_945GM) || 561 (ent->device == PCI_DEVICE_ID_INTEL_945GM) ||
562 (ent->device == PCI_DEVICE_ID_INTEL_945GME) ||
558 (ent->device == PCI_DEVICE_ID_INTEL_965G) || 563 (ent->device == PCI_DEVICE_ID_INTEL_965G) ||
559 (ent->device == PCI_DEVICE_ID_INTEL_965GM)) { 564 (ent->device == PCI_DEVICE_ID_INTEL_965GM)) {
560 565
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
index 8e6d6a4db0ad..8b26b27c2db6 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/intelfb/intelfbhw.c
@@ -143,6 +143,12 @@ int intelfbhw_get_chipset(struct pci_dev *pdev, struct intelfb_info *dinfo)
143 dinfo->mobile = 1; 143 dinfo->mobile = 1;
144 dinfo->pll_index = PLLS_I9xx; 144 dinfo->pll_index = PLLS_I9xx;
145 return 0; 145 return 0;
146 case PCI_DEVICE_ID_INTEL_945GME:
147 dinfo->name = "Intel(R) 945GME";
148 dinfo->chipset = INTEL_945GME;
149 dinfo->mobile = 1;
150 dinfo->pll_index = PLLS_I9xx;
151 return 0;
146 case PCI_DEVICE_ID_INTEL_965G: 152 case PCI_DEVICE_ID_INTEL_965G:
147 dinfo->name = "Intel(R) 965G"; 153 dinfo->name = "Intel(R) 965G";
148 dinfo->chipset = INTEL_965G; 154 dinfo->chipset = INTEL_965G;
@@ -186,6 +192,7 @@ int intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size,
186 case PCI_DEVICE_ID_INTEL_915GM: 192 case PCI_DEVICE_ID_INTEL_915GM:
187 case PCI_DEVICE_ID_INTEL_945G: 193 case PCI_DEVICE_ID_INTEL_945G:
188 case PCI_DEVICE_ID_INTEL_945GM: 194 case PCI_DEVICE_ID_INTEL_945GM:
195 case PCI_DEVICE_ID_INTEL_945GME:
189 case PCI_DEVICE_ID_INTEL_965G: 196 case PCI_DEVICE_ID_INTEL_965G:
190 case PCI_DEVICE_ID_INTEL_965GM: 197 case PCI_DEVICE_ID_INTEL_965GM:
191 /* 915, 945 and 965 chipsets support a 256MB aperture. 198 /* 915, 945 and 965 chipsets support a 256MB aperture.
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c
index c02136202792..8e7a275df50c 100644
--- a/drivers/video/matrox/matroxfb_base.c
+++ b/drivers/video/matrox/matroxfb_base.c
@@ -1453,6 +1453,13 @@ static struct board {
1453 MGA_G100, 1453 MGA_G100,
1454 &vbG100, 1454 &vbG100,
1455 "MGA-G100 (AGP)"}, 1455 "MGA-G100 (AGP)"},
1456 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200EV_PCI, 0xFF,
1457 0, 0,
1458 DEVF_G200,
1459 230000,
1460 MGA_G200,
1461 &vbG200,
1462 "MGA-G200eV (PCI)"},
1456 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_PCI, 0xFF, 1463 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_PCI, 0xFF,
1457 0, 0, 1464 0, 0,
1458 DEVF_G200, 1465 DEVF_G200,
@@ -2118,6 +2125,8 @@ static struct pci_device_id matroxfb_devices[] = {
2118 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 2125 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2119 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP, 2126 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP,
2120 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 2127 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2128 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200EV_PCI,
2129 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2121 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_PCI, 2130 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_PCI,
2122 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 2131 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2123 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, 2132 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP,
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c
index 25172b2a2a94..bfb802d26d5a 100644
--- a/drivers/video/neofb.c
+++ b/drivers/video/neofb.c
@@ -426,11 +426,11 @@ static void vgaHWProtect(int on)
426{ 426{
427 unsigned char tmp; 427 unsigned char tmp;
428 428
429 tmp = vga_rseq(NULL, 0x01);
429 if (on) { 430 if (on) {
430 /* 431 /*
431 * Turn off screen and disable sequencer. 432 * Turn off screen and disable sequencer.
432 */ 433 */
433 tmp = vga_rseq(NULL, 0x01);
434 vga_wseq(NULL, 0x00, 0x01); /* Synchronous Reset */ 434 vga_wseq(NULL, 0x00, 0x01); /* Synchronous Reset */
435 vga_wseq(NULL, 0x01, tmp | 0x20); /* disable the display */ 435 vga_wseq(NULL, 0x01, tmp | 0x20); /* disable the display */
436 436
@@ -439,7 +439,6 @@ static void vgaHWProtect(int on)
439 /* 439 /*
440 * Reenable sequencer, then turn on screen. 440 * Reenable sequencer, then turn on screen.
441 */ 441 */
442 tmp = vga_rseq(NULL, 0x01);
443 vga_wseq(NULL, 0x01, tmp & ~0x20); /* reenable display */ 442 vga_wseq(NULL, 0x01, tmp & ~0x20); /* reenable display */
444 vga_wseq(NULL, 0x00, 0x03); /* clear synchronousreset */ 443 vga_wseq(NULL, 0x00, 0x03); /* clear synchronousreset */
445 444
@@ -558,14 +557,12 @@ neofb_open(struct fb_info *info, int user)
558{ 557{
559 struct neofb_par *par = info->par; 558 struct neofb_par *par = info->par;
560 559
561 mutex_lock(&par->open_lock);
562 if (!par->ref_count) { 560 if (!par->ref_count) {
563 memset(&par->state, 0, sizeof(struct vgastate)); 561 memset(&par->state, 0, sizeof(struct vgastate));
564 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS; 562 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS;
565 save_vga(&par->state); 563 save_vga(&par->state);
566 } 564 }
567 par->ref_count++; 565 par->ref_count++;
568 mutex_unlock(&par->open_lock);
569 566
570 return 0; 567 return 0;
571} 568}
@@ -575,16 +572,13 @@ neofb_release(struct fb_info *info, int user)
575{ 572{
576 struct neofb_par *par = info->par; 573 struct neofb_par *par = info->par;
577 574
578 mutex_lock(&par->open_lock); 575 if (!par->ref_count)
579 if (!par->ref_count) {
580 mutex_unlock(&par->open_lock);
581 return -EINVAL; 576 return -EINVAL;
582 } 577
583 if (par->ref_count == 1) { 578 if (par->ref_count == 1) {
584 restore_vga(&par->state); 579 restore_vga(&par->state);
585 } 580 }
586 par->ref_count--; 581 par->ref_count--;
587 mutex_unlock(&par->open_lock);
588 582
589 return 0; 583 return 0;
590} 584}
@@ -648,10 +642,10 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
648 var->blue.msb_right = 0; 642 var->blue.msb_right = 0;
649 var->transp.msb_right = 0; 643 var->transp.msb_right = 0;
650 644
645 var->transp.offset = 0;
646 var->transp.length = 0;
651 switch (var->bits_per_pixel) { 647 switch (var->bits_per_pixel) {
652 case 8: /* PSEUDOCOLOUR, 256 */ 648 case 8: /* PSEUDOCOLOUR, 256 */
653 var->transp.offset = 0;
654 var->transp.length = 0;
655 var->red.offset = 0; 649 var->red.offset = 0;
656 var->red.length = 8; 650 var->red.length = 8;
657 var->green.offset = 0; 651 var->green.offset = 0;
@@ -661,8 +655,6 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
661 break; 655 break;
662 656
663 case 16: /* DIRECTCOLOUR, 64k */ 657 case 16: /* DIRECTCOLOUR, 64k */
664 var->transp.offset = 0;
665 var->transp.length = 0;
666 var->red.offset = 11; 658 var->red.offset = 11;
667 var->red.length = 5; 659 var->red.length = 5;
668 var->green.offset = 5; 660 var->green.offset = 5;
@@ -672,8 +664,6 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
672 break; 664 break;
673 665
674 case 24: /* TRUECOLOUR, 16m */ 666 case 24: /* TRUECOLOUR, 16m */
675 var->transp.offset = 0;
676 var->transp.length = 0;
677 var->red.offset = 16; 667 var->red.offset = 16;
678 var->red.length = 8; 668 var->red.length = 8;
679 var->green.offset = 8; 669 var->green.offset = 8;
@@ -704,8 +694,6 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
704 if (vramlen > 4 * 1024 * 1024) 694 if (vramlen > 4 * 1024 * 1024)
705 vramlen = 4 * 1024 * 1024; 695 vramlen = 4 * 1024 * 1024;
706 696
707 if (var->yres_virtual < var->yres)
708 var->yres_virtual = var->yres;
709 if (var->xres_virtual < var->xres) 697 if (var->xres_virtual < var->xres)
710 var->xres_virtual = var->xres; 698 var->xres_virtual = var->xres;
711 699
@@ -722,8 +710,6 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
722 if it was possible. We should return -EINVAL, but I disagree */ 710 if it was possible. We should return -EINVAL, but I disagree */
723 if (var->yres_virtual < var->yres) 711 if (var->yres_virtual < var->yres)
724 var->yres = var->yres_virtual; 712 var->yres = var->yres_virtual;
725 if (var->xres_virtual < var->xres)
726 var->xres = var->xres_virtual;
727 if (var->xoffset + var->xres > var->xres_virtual) 713 if (var->xoffset + var->xres > var->xres_virtual)
728 var->xoffset = var->xres_virtual - var->xres; 714 var->xoffset = var->xres_virtual - var->xres;
729 if (var->yoffset + var->yres > var->yres_virtual) 715 if (var->yoffset + var->yres > var->yres_virtual)
@@ -1186,8 +1172,11 @@ static int neofb_set_par(struct fb_info *info)
1186 return 0; 1172 return 0;
1187} 1173}
1188 1174
1189static void neofb_update_start(struct fb_info *info, 1175/*
1190 struct fb_var_screeninfo *var) 1176 * Pan or Wrap the Display
1177 */
1178static int neofb_pan_display(struct fb_var_screeninfo *var,
1179 struct fb_info *info)
1191{ 1180{
1192 struct neofb_par *par = info->par; 1181 struct neofb_par *par = info->par;
1193 struct vgastate *state = &par->state; 1182 struct vgastate *state = &par->state;
@@ -1216,35 +1205,7 @@ static void neofb_update_start(struct fb_info *info,
1216 vga_wgfx(state->vgabase, 0x0E, (((Base >> 16) & 0x0f) | (oldExtCRTDispAddr & 0xf0))); 1205 vga_wgfx(state->vgabase, 0x0E, (((Base >> 16) & 0x0f) | (oldExtCRTDispAddr & 0xf0)));
1217 1206
1218 neoLock(state); 1207 neoLock(state);
1219}
1220
1221/*
1222 * Pan or Wrap the Display
1223 */
1224static int neofb_pan_display(struct fb_var_screeninfo *var,
1225 struct fb_info *info)
1226{
1227 u_int y_bottom;
1228
1229 y_bottom = var->yoffset;
1230
1231 if (!(var->vmode & FB_VMODE_YWRAP))
1232 y_bottom += var->yres;
1233 1208
1234 if (var->xoffset > (var->xres_virtual - var->xres))
1235 return -EINVAL;
1236 if (y_bottom > info->var.yres_virtual)
1237 return -EINVAL;
1238
1239 neofb_update_start(info, var);
1240
1241 info->var.xoffset = var->xoffset;
1242 info->var.yoffset = var->yoffset;
1243
1244 if (var->vmode & FB_VMODE_YWRAP)
1245 info->var.vmode |= FB_VMODE_YWRAP;
1246 else
1247 info->var.vmode &= ~FB_VMODE_YWRAP;
1248 return 0; 1209 return 0;
1249} 1210}
1250 1211
@@ -1992,7 +1953,6 @@ static struct fb_info *__devinit neo_alloc_fb_info(struct pci_dev *dev, const st
1992 1953
1993 info->fix.accel = id->driver_data; 1954 info->fix.accel = id->driver_data;
1994 1955
1995 mutex_init(&par->open_lock);
1996 par->pci_burst = !nopciburst; 1956 par->pci_burst = !nopciburst;
1997 par->lcd_stretch = !nostretch; 1957 par->lcd_stretch = !nostretch;
1998 par->libretto = libretto; 1958 par->libretto = libretto;
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
index 6efcf89e7fbe..dfb72f5e4c96 100644
--- a/drivers/video/omap/dispc.c
+++ b/drivers/video/omap/dispc.c
@@ -156,7 +156,7 @@ struct resmap {
156}; 156};
157 157
158static struct { 158static struct {
159 u32 base; 159 void __iomem *base;
160 160
161 struct omapfb_mem_desc mem_desc; 161 struct omapfb_mem_desc mem_desc;
162 struct resmap *res_map[DISPC_MEMTYPE_NUM]; 162 struct resmap *res_map[DISPC_MEMTYPE_NUM];
@@ -212,9 +212,9 @@ static void enable_rfbi_mode(int enable)
212 dispc_write_reg(DISPC_CONTROL, l); 212 dispc_write_reg(DISPC_CONTROL, l);
213 213
214 /* Set bypass mode in RFBI module */ 214 /* Set bypass mode in RFBI module */
215 l = __raw_readl(io_p2v(RFBI_CONTROL)); 215 l = __raw_readl(IO_ADDRESS(RFBI_CONTROL));
216 l |= enable ? 0 : (1 << 1); 216 l |= enable ? 0 : (1 << 1);
217 __raw_writel(l, io_p2v(RFBI_CONTROL)); 217 __raw_writel(l, IO_ADDRESS(RFBI_CONTROL));
218} 218}
219 219
220static void set_lcd_data_lines(int data_lines) 220static void set_lcd_data_lines(int data_lines)
@@ -1349,14 +1349,19 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode,
1349 1349
1350 memset(&dispc, 0, sizeof(dispc)); 1350 memset(&dispc, 0, sizeof(dispc));
1351 1351
1352 dispc.base = io_p2v(DISPC_BASE); 1352 dispc.base = ioremap(DISPC_BASE, SZ_1K);
1353 if (!dispc.base) {
1354 dev_err(fbdev->dev, "can't ioremap DISPC\n");
1355 return -ENOMEM;
1356 }
1357
1353 dispc.fbdev = fbdev; 1358 dispc.fbdev = fbdev;
1354 dispc.ext_mode = ext_mode; 1359 dispc.ext_mode = ext_mode;
1355 1360
1356 init_completion(&dispc.frame_done); 1361 init_completion(&dispc.frame_done);
1357 1362
1358 if ((r = get_dss_clocks()) < 0) 1363 if ((r = get_dss_clocks()) < 0)
1359 return r; 1364 goto fail0;
1360 1365
1361 enable_interface_clocks(1); 1366 enable_interface_clocks(1);
1362 enable_lcd_clocks(1); 1367 enable_lcd_clocks(1);
@@ -1414,7 +1419,7 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode,
1414 } 1419 }
1415 1420
1416 /* L3 firewall setting: enable access to OCM RAM */ 1421 /* L3 firewall setting: enable access to OCM RAM */
1417 __raw_writel(0x402000b0, io_p2v(0x680050a0)); 1422 __raw_writel(0x402000b0, IO_ADDRESS(0x680050a0));
1418 1423
1419 if ((r = alloc_palette_ram()) < 0) 1424 if ((r = alloc_palette_ram()) < 0)
1420 goto fail2; 1425 goto fail2;
@@ -1464,7 +1469,8 @@ fail1:
1464 enable_lcd_clocks(0); 1469 enable_lcd_clocks(0);
1465 enable_interface_clocks(0); 1470 enable_interface_clocks(0);
1466 put_dss_clocks(); 1471 put_dss_clocks();
1467 1472fail0:
1473 iounmap(dispc.base);
1468 return r; 1474 return r;
1469} 1475}
1470 1476
@@ -1481,6 +1487,7 @@ static void omap_dispc_cleanup(void)
1481 free_irq(INT_24XX_DSS_IRQ, dispc.fbdev); 1487 free_irq(INT_24XX_DSS_IRQ, dispc.fbdev);
1482 enable_interface_clocks(0); 1488 enable_interface_clocks(0);
1483 put_dss_clocks(); 1489 put_dss_clocks();
1490 iounmap(dispc.base);
1484} 1491}
1485 1492
1486const struct lcd_ctrl omap2_int_ctrl = { 1493const struct lcd_ctrl omap2_int_ctrl = {
diff --git a/drivers/video/omap/dispc.h b/drivers/video/omap/dispc.h
index eb1512b56ce8..ef720a78f6d5 100644
--- a/drivers/video/omap/dispc.h
+++ b/drivers/video/omap/dispc.h
@@ -40,4 +40,6 @@ extern void omap_dispc_enable_digit_out(int enable);
40extern int omap_dispc_request_irq(void (*callback)(void *data), void *data); 40extern int omap_dispc_request_irq(void (*callback)(void *data), void *data);
41extern void omap_dispc_free_irq(void); 41extern void omap_dispc_free_irq(void);
42 42
43extern const struct lcd_ctrl omap2_int_ctrl;
44
43#endif 45#endif
diff --git a/drivers/video/omap/lcd_h4.c b/drivers/video/omap/lcd_h4.c
index 88c19d424ef7..6ff56430341b 100644
--- a/drivers/video/omap/lcd_h4.c
+++ b/drivers/video/omap/lcd_h4.c
@@ -47,7 +47,7 @@ static unsigned long h4_panel_get_caps(struct lcd_panel *panel)
47 return 0; 47 return 0;
48} 48}
49 49
50struct lcd_panel h4_panel = { 50static struct lcd_panel h4_panel = {
51 .name = "h4", 51 .name = "h4",
52 .config = OMAP_LCDC_PANEL_TFT, 52 .config = OMAP_LCDC_PANEL_TFT,
53 53
@@ -91,7 +91,7 @@ static int h4_panel_resume(struct platform_device *pdev)
91 return 0; 91 return 0;
92} 92}
93 93
94struct platform_driver h4_panel_driver = { 94static struct platform_driver h4_panel_driver = {
95 .probe = h4_panel_probe, 95 .probe = h4_panel_probe,
96 .remove = h4_panel_remove, 96 .remove = h4_panel_remove,
97 .suspend = h4_panel_suspend, 97 .suspend = h4_panel_suspend,
diff --git a/drivers/video/omap/lcd_inn1610.c b/drivers/video/omap/lcd_inn1610.c
index 6a42c6a0cd99..4c4f7ee6d733 100644
--- a/drivers/video/omap/lcd_inn1610.c
+++ b/drivers/video/omap/lcd_inn1610.c
@@ -32,43 +32,43 @@ static int innovator1610_panel_init(struct lcd_panel *panel,
32{ 32{
33 int r = 0; 33 int r = 0;
34 34
35 if (omap_request_gpio(14)) { 35 if (gpio_request(14, "lcd_en0")) {
36 pr_err(MODULE_NAME ": can't request GPIO 14\n"); 36 pr_err(MODULE_NAME ": can't request GPIO 14\n");
37 r = -1; 37 r = -1;
38 goto exit; 38 goto exit;
39 } 39 }
40 if (omap_request_gpio(15)) { 40 if (gpio_request(15, "lcd_en1")) {
41 pr_err(MODULE_NAME ": can't request GPIO 15\n"); 41 pr_err(MODULE_NAME ": can't request GPIO 15\n");
42 omap_free_gpio(14); 42 gpio_free(14);
43 r = -1; 43 r = -1;
44 goto exit; 44 goto exit;
45 } 45 }
46 /* configure GPIO(14, 15) as outputs */ 46 /* configure GPIO(14, 15) as outputs */
47 omap_set_gpio_direction(14, 0); 47 gpio_direction_output(14, 0);
48 omap_set_gpio_direction(15, 0); 48 gpio_direction_output(15, 0);
49exit: 49exit:
50 return r; 50 return r;
51} 51}
52 52
53static void innovator1610_panel_cleanup(struct lcd_panel *panel) 53static void innovator1610_panel_cleanup(struct lcd_panel *panel)
54{ 54{
55 omap_free_gpio(15); 55 gpio_free(15);
56 omap_free_gpio(14); 56 gpio_free(14);
57} 57}
58 58
59static int innovator1610_panel_enable(struct lcd_panel *panel) 59static int innovator1610_panel_enable(struct lcd_panel *panel)
60{ 60{
61 /* set GPIO14 and GPIO15 high */ 61 /* set GPIO14 and GPIO15 high */
62 omap_set_gpio_dataout(14, 1); 62 gpio_set_value(14, 1);
63 omap_set_gpio_dataout(15, 1); 63 gpio_set_value(15, 1);
64 return 0; 64 return 0;
65} 65}
66 66
67static void innovator1610_panel_disable(struct lcd_panel *panel) 67static void innovator1610_panel_disable(struct lcd_panel *panel)
68{ 68{
69 /* set GPIO13, GPIO14 and GPIO15 low */ 69 /* set GPIO13, GPIO14 and GPIO15 low */
70 omap_set_gpio_dataout(14, 0); 70 gpio_set_value(14, 0);
71 omap_set_gpio_dataout(15, 0); 71 gpio_set_value(15, 0);
72} 72}
73 73
74static unsigned long innovator1610_panel_get_caps(struct lcd_panel *panel) 74static unsigned long innovator1610_panel_get_caps(struct lcd_panel *panel)
diff --git a/drivers/video/omap/lcd_osk.c b/drivers/video/omap/lcd_osk.c
index a4a725f427a4..379c96d36da5 100644
--- a/drivers/video/omap/lcd_osk.c
+++ b/drivers/video/omap/lcd_osk.c
@@ -29,6 +29,7 @@
29 29
30static int osk_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev) 30static int osk_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev)
31{ 31{
32 /* gpio2 was allocated in board init */
32 return 0; 33 return 0;
33} 34}
34 35
@@ -47,11 +48,8 @@ static int osk_panel_enable(struct lcd_panel *panel)
47 /* Set PWL level */ 48 /* Set PWL level */
48 omap_writeb(0xFF, OMAP_PWL_ENABLE); 49 omap_writeb(0xFF, OMAP_PWL_ENABLE);
49 50
50 /* configure GPIO2 as output */ 51 /* set GPIO2 high (lcd power enabled) */
51 omap_set_gpio_direction(2, 0); 52 gpio_set_value(2, 1);
52
53 /* set GPIO2 high */
54 omap_set_gpio_dataout(2, 1);
55 53
56 return 0; 54 return 0;
57} 55}
@@ -65,7 +63,7 @@ static void osk_panel_disable(struct lcd_panel *panel)
65 omap_writeb(0x00, OMAP_PWL_CLK_ENABLE); 63 omap_writeb(0x00, OMAP_PWL_CLK_ENABLE);
66 64
67 /* set GPIO2 low */ 65 /* set GPIO2 low */
68 omap_set_gpio_dataout(2, 0); 66 gpio_set_value(2, 0);
69} 67}
70 68
71static unsigned long osk_panel_get_caps(struct lcd_panel *panel) 69static unsigned long osk_panel_get_caps(struct lcd_panel *panel)
diff --git a/drivers/video/omap/lcd_sx1.c b/drivers/video/omap/lcd_sx1.c
index caa6a896cb8b..e55de201b8ff 100644
--- a/drivers/video/omap/lcd_sx1.c
+++ b/drivers/video/omap/lcd_sx1.c
@@ -81,21 +81,21 @@ static void epson_sendbyte(int flag, unsigned char byte)
81 int i, shifter = 0x80; 81 int i, shifter = 0x80;
82 82
83 if (!flag) 83 if (!flag)
84 omap_set_gpio_dataout(_A_LCD_SSC_A0, 0); 84 gpio_set_value(_A_LCD_SSC_A0, 0);
85 mdelay(2); 85 mdelay(2);
86 omap_set_gpio_dataout(A_LCD_SSC_RD, 1); 86 gpio_set_value(A_LCD_SSC_RD, 1);
87 87
88 omap_set_gpio_dataout(A_LCD_SSC_SD, flag); 88 gpio_set_value(A_LCD_SSC_SD, flag);
89 89
90 OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2200); 90 OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2200);
91 OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2202); 91 OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2202);
92 for (i = 0; i < 8; i++) { 92 for (i = 0; i < 8; i++) {
93 OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2200); 93 OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2200);
94 omap_set_gpio_dataout(A_LCD_SSC_SD, shifter & byte); 94 gpio_set_value(A_LCD_SSC_SD, shifter & byte);
95 OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2202); 95 OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2202);
96 shifter >>= 1; 96 shifter >>= 1;
97 } 97 }
98 omap_set_gpio_dataout(_A_LCD_SSC_A0, 1); 98 gpio_set_value(_A_LCD_SSC_A0, 1);
99} 99}
100 100
101static void init_system(void) 101static void init_system(void)
@@ -107,25 +107,18 @@ static void init_system(void)
107static void setup_GPIO(void) 107static void setup_GPIO(void)
108{ 108{
109 /* new wave */ 109 /* new wave */
110 omap_request_gpio(A_LCD_SSC_RD); 110 gpio_request(A_LCD_SSC_RD, "lcd_ssc_rd");
111 omap_request_gpio(A_LCD_SSC_SD); 111 gpio_request(A_LCD_SSC_SD, "lcd_ssc_sd");
112 omap_request_gpio(_A_LCD_RESET); 112 gpio_request(_A_LCD_RESET, "lcd_reset");
113 omap_request_gpio(_A_LCD_SSC_CS); 113 gpio_request(_A_LCD_SSC_CS, "lcd_ssc_cs");
114 omap_request_gpio(_A_LCD_SSC_A0); 114 gpio_request(_A_LCD_SSC_A0, "lcd_ssc_a0");
115 115
116 /* set all GPIOs to output */ 116 /* set GPIOs to output, with initial data */
117 omap_set_gpio_direction(A_LCD_SSC_RD, 0); 117 gpio_direction_output(A_LCD_SSC_RD, 1);
118 omap_set_gpio_direction(A_LCD_SSC_SD, 0); 118 gpio_direction_output(A_LCD_SSC_SD, 0);
119 omap_set_gpio_direction(_A_LCD_RESET, 0); 119 gpio_direction_output(_A_LCD_RESET, 0);
120 omap_set_gpio_direction(_A_LCD_SSC_CS, 0); 120 gpio_direction_output(_A_LCD_SSC_CS, 1);
121 omap_set_gpio_direction(_A_LCD_SSC_A0, 0); 121 gpio_direction_output(_A_LCD_SSC_A0, 1);
122
123 /* set GPIO data */
124 omap_set_gpio_dataout(A_LCD_SSC_RD, 1);
125 omap_set_gpio_dataout(A_LCD_SSC_SD, 0);
126 omap_set_gpio_dataout(_A_LCD_RESET, 0);
127 omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
128 omap_set_gpio_dataout(_A_LCD_SSC_A0, 1);
129} 122}
130 123
131static void display_init(void) 124static void display_init(void)
@@ -139,61 +132,61 @@ static void display_init(void)
139 mdelay(2); 132 mdelay(2);
140 133
141 /* reset LCD */ 134 /* reset LCD */
142 omap_set_gpio_dataout(A_LCD_SSC_SD, 1); 135 gpio_set_value(A_LCD_SSC_SD, 1);
143 epson_sendbyte(0, 0x25); 136 epson_sendbyte(0, 0x25);
144 137
145 omap_set_gpio_dataout(_A_LCD_RESET, 0); 138 gpio_set_value(_A_LCD_RESET, 0);
146 mdelay(10); 139 mdelay(10);
147 omap_set_gpio_dataout(_A_LCD_RESET, 1); 140 gpio_set_value(_A_LCD_RESET, 1);
148 141
149 omap_set_gpio_dataout(_A_LCD_SSC_CS, 1); 142 gpio_set_value(_A_LCD_SSC_CS, 1);
150 mdelay(2); 143 mdelay(2);
151 omap_set_gpio_dataout(_A_LCD_SSC_CS, 0); 144 gpio_set_value(_A_LCD_SSC_CS, 0);
152 145
153 /* init LCD, phase 1 */ 146 /* init LCD, phase 1 */
154 epson_sendbyte(0, 0xCA); 147 epson_sendbyte(0, 0xCA);
155 for (i = 0; i < 10; i++) 148 for (i = 0; i < 10; i++)
156 epson_sendbyte(1, INIT_1[i]); 149 epson_sendbyte(1, INIT_1[i]);
157 omap_set_gpio_dataout(_A_LCD_SSC_CS, 1); 150 gpio_set_value(_A_LCD_SSC_CS, 1);
158 omap_set_gpio_dataout(_A_LCD_SSC_CS, 0); 151 gpio_set_value(_A_LCD_SSC_CS, 0);
159 152
160 /* init LCD phase 2 */ 153 /* init LCD phase 2 */
161 epson_sendbyte(0, 0xCB); 154 epson_sendbyte(0, 0xCB);
162 for (i = 0; i < 125; i++) 155 for (i = 0; i < 125; i++)
163 epson_sendbyte(1, INIT_2[i]); 156 epson_sendbyte(1, INIT_2[i]);
164 omap_set_gpio_dataout(_A_LCD_SSC_CS, 1); 157 gpio_set_value(_A_LCD_SSC_CS, 1);
165 omap_set_gpio_dataout(_A_LCD_SSC_CS, 0); 158 gpio_set_value(_A_LCD_SSC_CS, 0);
166 159
167 /* init LCD phase 2a */ 160 /* init LCD phase 2a */
168 epson_sendbyte(0, 0xCC); 161 epson_sendbyte(0, 0xCC);
169 for (i = 0; i < 14; i++) 162 for (i = 0; i < 14; i++)
170 epson_sendbyte(1, INIT_3[i]); 163 epson_sendbyte(1, INIT_3[i]);
171 omap_set_gpio_dataout(_A_LCD_SSC_CS, 1); 164 gpio_set_value(_A_LCD_SSC_CS, 1);
172 omap_set_gpio_dataout(_A_LCD_SSC_CS, 0); 165 gpio_set_value(_A_LCD_SSC_CS, 0);
173 166
174 /* init LCD phase 3 */ 167 /* init LCD phase 3 */
175 epson_sendbyte(0, 0xBC); 168 epson_sendbyte(0, 0xBC);
176 epson_sendbyte(1, 0x08); 169 epson_sendbyte(1, 0x08);
177 omap_set_gpio_dataout(_A_LCD_SSC_CS, 1); 170 gpio_set_value(_A_LCD_SSC_CS, 1);
178 omap_set_gpio_dataout(_A_LCD_SSC_CS, 0); 171 gpio_set_value(_A_LCD_SSC_CS, 0);
179 172
180 /* init LCD phase 4 */ 173 /* init LCD phase 4 */
181 epson_sendbyte(0, 0x07); 174 epson_sendbyte(0, 0x07);
182 epson_sendbyte(1, 0x05); 175 epson_sendbyte(1, 0x05);
183 omap_set_gpio_dataout(_A_LCD_SSC_CS, 1); 176 gpio_set_value(_A_LCD_SSC_CS, 1);
184 omap_set_gpio_dataout(_A_LCD_SSC_CS, 0); 177 gpio_set_value(_A_LCD_SSC_CS, 0);
185 178
186 /* init LCD phase 5 */ 179 /* init LCD phase 5 */
187 epson_sendbyte(0, 0x94); 180 epson_sendbyte(0, 0x94);
188 omap_set_gpio_dataout(_A_LCD_SSC_CS, 1); 181 gpio_set_value(_A_LCD_SSC_CS, 1);
189 omap_set_gpio_dataout(_A_LCD_SSC_CS, 0); 182 gpio_set_value(_A_LCD_SSC_CS, 0);
190 183
191 /* init LCD phase 6 */ 184 /* init LCD phase 6 */
192 epson_sendbyte(0, 0xC6); 185 epson_sendbyte(0, 0xC6);
193 epson_sendbyte(1, 0x80); 186 epson_sendbyte(1, 0x80);
194 omap_set_gpio_dataout(_A_LCD_SSC_CS, 1); 187 gpio_set_value(_A_LCD_SSC_CS, 1);
195 mdelay(100); /* used to be 1000 */ 188 mdelay(100); /* used to be 1000 */
196 omap_set_gpio_dataout(_A_LCD_SSC_CS, 0); 189 gpio_set_value(_A_LCD_SSC_CS, 0);
197 190
198 /* init LCD phase 7 */ 191 /* init LCD phase 7 */
199 epson_sendbyte(0, 0x16); 192 epson_sendbyte(0, 0x16);
@@ -201,8 +194,8 @@ static void display_init(void)
201 epson_sendbyte(1, 0x00); 194 epson_sendbyte(1, 0x00);
202 epson_sendbyte(1, 0xB1); 195 epson_sendbyte(1, 0xB1);
203 epson_sendbyte(1, 0x00); 196 epson_sendbyte(1, 0x00);
204 omap_set_gpio_dataout(_A_LCD_SSC_CS, 1); 197 gpio_set_value(_A_LCD_SSC_CS, 1);
205 omap_set_gpio_dataout(_A_LCD_SSC_CS, 0); 198 gpio_set_value(_A_LCD_SSC_CS, 0);
206 199
207 /* init LCD phase 8 */ 200 /* init LCD phase 8 */
208 epson_sendbyte(0, 0x76); 201 epson_sendbyte(0, 0x76);
@@ -210,12 +203,12 @@ static void display_init(void)
210 epson_sendbyte(1, 0x00); 203 epson_sendbyte(1, 0x00);
211 epson_sendbyte(1, 0xDB); 204 epson_sendbyte(1, 0xDB);
212 epson_sendbyte(1, 0x00); 205 epson_sendbyte(1, 0x00);
213 omap_set_gpio_dataout(_A_LCD_SSC_CS, 1); 206 gpio_set_value(_A_LCD_SSC_CS, 1);
214 omap_set_gpio_dataout(_A_LCD_SSC_CS, 0); 207 gpio_set_value(_A_LCD_SSC_CS, 0);
215 208
216 /* init LCD phase 9 */ 209 /* init LCD phase 9 */
217 epson_sendbyte(0, 0xAF); 210 epson_sendbyte(0, 0xAF);
218 omap_set_gpio_dataout(_A_LCD_SSC_CS, 1); 211 gpio_set_value(_A_LCD_SSC_CS, 1);
219} 212}
220 213
221static int sx1_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev) 214static int sx1_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev)
@@ -231,18 +224,18 @@ static void sx1_panel_disable(struct lcd_panel *panel)
231{ 224{
232 printk(KERN_INFO "SX1: LCD panel disable\n"); 225 printk(KERN_INFO "SX1: LCD panel disable\n");
233 sx1_setmmipower(0); 226 sx1_setmmipower(0);
234 omap_set_gpio_dataout(_A_LCD_SSC_CS, 1); 227 gpio_set_value(_A_LCD_SSC_CS, 1);
235 228
236 epson_sendbyte(0, 0x25); 229 epson_sendbyte(0, 0x25);
237 omap_set_gpio_dataout(_A_LCD_SSC_CS, 0); 230 gpio_set_value(_A_LCD_SSC_CS, 0);
238 231
239 epson_sendbyte(0, 0xAE); 232 epson_sendbyte(0, 0xAE);
240 omap_set_gpio_dataout(_A_LCD_SSC_CS, 1); 233 gpio_set_value(_A_LCD_SSC_CS, 1);
241 mdelay(100); 234 mdelay(100);
242 omap_set_gpio_dataout(_A_LCD_SSC_CS, 0); 235 gpio_set_value(_A_LCD_SSC_CS, 0);
243 236
244 epson_sendbyte(0, 0x95); 237 epson_sendbyte(0, 0x95);
245 omap_set_gpio_dataout(_A_LCD_SSC_CS, 1); 238 gpio_set_value(_A_LCD_SSC_CS, 1);
246} 239}
247 240
248static int sx1_panel_enable(struct lcd_panel *panel) 241static int sx1_panel_enable(struct lcd_panel *panel)
diff --git a/drivers/video/omap/lcdc.c b/drivers/video/omap/lcdc.c
index 83514f066712..6e2ea7518761 100644
--- a/drivers/video/omap/lcdc.c
+++ b/drivers/video/omap/lcdc.c
@@ -34,6 +34,8 @@
34 34
35#include <asm/mach-types.h> 35#include <asm/mach-types.h>
36 36
37#include "lcdc.h"
38
37#define MODULE_NAME "lcdc" 39#define MODULE_NAME "lcdc"
38 40
39#define OMAP_LCDC_BASE 0xfffec000 41#define OMAP_LCDC_BASE 0xfffec000
diff --git a/drivers/video/omap/lcdc.h b/drivers/video/omap/lcdc.h
index adb731e5314a..845222270db3 100644
--- a/drivers/video/omap/lcdc.h
+++ b/drivers/video/omap/lcdc.h
@@ -4,4 +4,6 @@
4int omap_lcdc_set_dma_callback(void (*callback)(void *data), void *data); 4int omap_lcdc_set_dma_callback(void (*callback)(void *data), void *data);
5void omap_lcdc_free_dma_callback(void); 5void omap_lcdc_free_dma_callback(void);
6 6
7extern const struct lcd_ctrl omap1_int_ctrl;
8
7#endif 9#endif
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
index 51a138bd113c..5a5e407dc45f 100644
--- a/drivers/video/omap/omapfb_main.c
+++ b/drivers/video/omap/omapfb_main.c
@@ -31,11 +31,14 @@
31#include <mach/dma.h> 31#include <mach/dma.h>
32#include <mach/omapfb.h> 32#include <mach/omapfb.h>
33 33
34#include "lcdc.h"
35#include "dispc.h"
36
34#define MODULE_NAME "omapfb" 37#define MODULE_NAME "omapfb"
35 38
36static unsigned int def_accel; 39static unsigned int def_accel;
37static unsigned long def_vram[OMAPFB_PLANE_NUM]; 40static unsigned long def_vram[OMAPFB_PLANE_NUM];
38static int def_vram_cnt; 41static unsigned int def_vram_cnt;
39static unsigned long def_vxres; 42static unsigned long def_vxres;
40static unsigned long def_vyres; 43static unsigned long def_vyres;
41static unsigned int def_rotate; 44static unsigned int def_rotate;
@@ -84,12 +87,10 @@ static struct caps_table_struct color_caps[] = {
84 * LCD panel 87 * LCD panel
85 * --------------------------------------------------------------------------- 88 * ---------------------------------------------------------------------------
86 */ 89 */
87extern struct lcd_ctrl omap1_int_ctrl;
88extern struct lcd_ctrl omap2_int_ctrl;
89extern struct lcd_ctrl hwa742_ctrl; 90extern struct lcd_ctrl hwa742_ctrl;
90extern struct lcd_ctrl blizzard_ctrl; 91extern struct lcd_ctrl blizzard_ctrl;
91 92
92static struct lcd_ctrl *ctrls[] = { 93static const struct lcd_ctrl *ctrls[] = {
93#ifdef CONFIG_ARCH_OMAP1 94#ifdef CONFIG_ARCH_OMAP1
94 &omap1_int_ctrl, 95 &omap1_int_ctrl,
95#else 96#else
@@ -740,7 +741,7 @@ static int omapfb_update_win(struct fb_info *fbi,
740 int ret; 741 int ret;
741 742
742 omapfb_rqueue_lock(plane->fbdev); 743 omapfb_rqueue_lock(plane->fbdev);
743 ret = omapfb_update_window_async(fbi, win, NULL, 0); 744 ret = omapfb_update_window_async(fbi, win, NULL, NULL);
744 omapfb_rqueue_unlock(plane->fbdev); 745 omapfb_rqueue_unlock(plane->fbdev);
745 746
746 return ret; 747 return ret;
@@ -768,7 +769,7 @@ static int omapfb_update_full_screen(struct fb_info *fbi)
768 win.format = 0; 769 win.format = 0;
769 770
770 omapfb_rqueue_lock(fbdev); 771 omapfb_rqueue_lock(fbdev);
771 r = fbdev->ctrl->update_window(fbi, &win, NULL, 0); 772 r = fbdev->ctrl->update_window(fbi, &win, NULL, NULL);
772 omapfb_rqueue_unlock(fbdev); 773 omapfb_rqueue_unlock(fbdev);
773 774
774 return r; 775 return r;
@@ -1047,7 +1048,7 @@ void omapfb_write_first_pixel(struct omapfb_device *fbdev, u16 pixval)
1047 win.height = 2; 1048 win.height = 2;
1048 win.out_width = 2; 1049 win.out_width = 2;
1049 win.out_height = 2; 1050 win.out_height = 2;
1050 fbdev->ctrl->update_window(fbdev->fb_info[0], &win, NULL, 0); 1051 fbdev->ctrl->update_window(fbdev->fb_info[0], &win, NULL, NULL);
1051 } 1052 }
1052 omapfb_rqueue_unlock(fbdev); 1053 omapfb_rqueue_unlock(fbdev);
1053} 1054}
diff --git a/drivers/video/omap/rfbi.c b/drivers/video/omap/rfbi.c
index 4a6f13d3facf..a13c8dcad2a8 100644
--- a/drivers/video/omap/rfbi.c
+++ b/drivers/video/omap/rfbi.c
@@ -59,7 +59,7 @@
59#define DISPC_CONTROL 0x0040 59#define DISPC_CONTROL 0x0040
60 60
61static struct { 61static struct {
62 u32 base; 62 void __iomem *base;
63 void (*lcdc_callback)(void *data); 63 void (*lcdc_callback)(void *data);
64 void *lcdc_callback_data; 64 void *lcdc_callback_data;
65 unsigned long l4_khz; 65 unsigned long l4_khz;
@@ -518,7 +518,11 @@ static int rfbi_init(struct omapfb_device *fbdev)
518 int r; 518 int r;
519 519
520 rfbi.fbdev = fbdev; 520 rfbi.fbdev = fbdev;
521 rfbi.base = io_p2v(RFBI_BASE); 521 rfbi.base = ioremap(RFBI_BASE, SZ_1K);
522 if (!rfbi.base) {
523 dev_err(fbdev->dev, "can't ioremap RFBI\n");
524 return -ENOMEM;
525 }
522 526
523 if ((r = rfbi_get_clocks()) < 0) 527 if ((r = rfbi_get_clocks()) < 0)
524 return r; 528 return r;
@@ -566,6 +570,7 @@ static void rfbi_cleanup(void)
566{ 570{
567 omap_dispc_free_irq(); 571 omap_dispc_free_irq();
568 rfbi_put_clocks(); 572 rfbi_put_clocks();
573 iounmap(rfbi.base);
569} 574}
570 575
571const struct lcd_ctrl_extif omap2_ext_if = { 576const struct lcd_ctrl_extif omap2_ext_if = {
diff --git a/drivers/video/omap/sossi.c b/drivers/video/omap/sossi.c
index 6359353c2c67..a76946220249 100644
--- a/drivers/video/omap/sossi.c
+++ b/drivers/video/omap/sossi.c
@@ -574,7 +574,12 @@ static int sossi_init(struct omapfb_device *fbdev)
574 struct clk *dpll1out_ck; 574 struct clk *dpll1out_ck;
575 int r; 575 int r;
576 576
577 sossi.base = (void __iomem *)IO_ADDRESS(OMAP_SOSSI_BASE); 577 sossi.base = ioremap(OMAP_SOSSI_BASE, SZ_1K);
578 if (!sossi.base) {
579 dev_err(fbdev->dev, "can't ioremap SoSSI\n");
580 return -ENOMEM;
581 }
582
578 sossi.fbdev = fbdev; 583 sossi.fbdev = fbdev;
579 spin_lock_init(&sossi.lock); 584 spin_lock_init(&sossi.lock);
580 585
@@ -665,6 +670,7 @@ static void sossi_cleanup(void)
665{ 670{
666 omap_lcdc_free_dma_callback(); 671 omap_lcdc_free_dma_callback();
667 clk_put(sossi.fck); 672 clk_put(sossi.fck);
673 iounmap(sossi.base);
668} 674}
669 675
670struct lcd_ctrl_extif omap1_ext_if = { 676struct lcd_ctrl_extif omap1_ext_if = {
diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c
index b829dc7c5edf..a7b01d2724b5 100644
--- a/drivers/video/s1d13xxxfb.c
+++ b/drivers/video/s1d13xxxfb.c
@@ -50,6 +50,11 @@
50#define dbg(fmt, args...) do { } while (0) 50#define dbg(fmt, args...) do { } while (0)
51#endif 51#endif
52 52
53static const int __devinitconst s1d13xxxfb_revisions[] = {
54 S1D13506_CHIP_REV, /* Rev.4 on HP Jornada 7xx S1D13506 */
55 S1D13806_CHIP_REV, /* Rev.7 on .. */
56};
57
53/* 58/*
54 * Here we define the default struct fb_fix_screeninfo 59 * Here we define the default struct fb_fix_screeninfo
55 */ 60 */
@@ -538,6 +543,7 @@ s1d13xxxfb_probe(struct platform_device *pdev)
538 struct fb_info *info; 543 struct fb_info *info;
539 struct s1d13xxxfb_pdata *pdata = NULL; 544 struct s1d13xxxfb_pdata *pdata = NULL;
540 int ret = 0; 545 int ret = 0;
546 int i;
541 u8 revision; 547 u8 revision;
542 548
543 dbg("probe called: device is %p\n", pdev); 549 dbg("probe called: device is %p\n", pdev);
@@ -607,10 +613,19 @@ s1d13xxxfb_probe(struct platform_device *pdev)
607 goto bail; 613 goto bail;
608 } 614 }
609 615
610 revision = s1d13xxxfb_readreg(default_par, S1DREG_REV_CODE); 616 revision = s1d13xxxfb_readreg(default_par, S1DREG_REV_CODE) >> 2;
611 if ((revision >> 2) != S1D_CHIP_REV) { 617
612 printk(KERN_INFO PFX "chip not found: %i\n", (revision >> 2)); 618 ret = -ENODEV;
613 ret = -ENODEV; 619
620 for (i = 0; i < ARRAY_SIZE(s1d13xxxfb_revisions); i++) {
621 if (revision == s1d13xxxfb_revisions[i])
622 ret = 0;
623 }
624
625 if (!ret)
626 printk(KERN_INFO PFX "chip revision %i\n", revision);
627 else {
628 printk(KERN_INFO PFX "unknown chip revision %i\n", revision);
614 goto bail; 629 goto bail;
615 } 630 }
616 631
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
index 4599a4385bc9..14bd3f3680b8 100644
--- a/drivers/video/tdfxfb.c
+++ b/drivers/video/tdfxfb.c
@@ -1195,57 +1195,58 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev,
1195 return -ENOMEM; 1195 return -ENOMEM;
1196 1196
1197 default_par = info->par; 1197 default_par = info->par;
1198 info->fix = tdfx_fix;
1198 1199
1199 /* Configure the default fb_fix_screeninfo first */ 1200 /* Configure the default fb_fix_screeninfo first */
1200 switch (pdev->device) { 1201 switch (pdev->device) {
1201 case PCI_DEVICE_ID_3DFX_BANSHEE: 1202 case PCI_DEVICE_ID_3DFX_BANSHEE:
1202 strcpy(tdfx_fix.id, "3Dfx Banshee"); 1203 strcpy(info->fix.id, "3Dfx Banshee");
1203 default_par->max_pixclock = BANSHEE_MAX_PIXCLOCK; 1204 default_par->max_pixclock = BANSHEE_MAX_PIXCLOCK;
1204 break; 1205 break;
1205 case PCI_DEVICE_ID_3DFX_VOODOO3: 1206 case PCI_DEVICE_ID_3DFX_VOODOO3:
1206 strcpy(tdfx_fix.id, "3Dfx Voodoo3"); 1207 strcpy(info->fix.id, "3Dfx Voodoo3");
1207 default_par->max_pixclock = VOODOO3_MAX_PIXCLOCK; 1208 default_par->max_pixclock = VOODOO3_MAX_PIXCLOCK;
1208 break; 1209 break;
1209 case PCI_DEVICE_ID_3DFX_VOODOO5: 1210 case PCI_DEVICE_ID_3DFX_VOODOO5:
1210 strcpy(tdfx_fix.id, "3Dfx Voodoo5"); 1211 strcpy(info->fix.id, "3Dfx Voodoo5");
1211 default_par->max_pixclock = VOODOO5_MAX_PIXCLOCK; 1212 default_par->max_pixclock = VOODOO5_MAX_PIXCLOCK;
1212 break; 1213 break;
1213 } 1214 }
1214 1215
1215 tdfx_fix.mmio_start = pci_resource_start(pdev, 0); 1216 info->fix.mmio_start = pci_resource_start(pdev, 0);
1216 tdfx_fix.mmio_len = pci_resource_len(pdev, 0); 1217 info->fix.mmio_len = pci_resource_len(pdev, 0);
1217 if (!request_mem_region(tdfx_fix.mmio_start, tdfx_fix.mmio_len, 1218 if (!request_mem_region(info->fix.mmio_start, info->fix.mmio_len,
1218 "tdfx regbase")) { 1219 "tdfx regbase")) {
1219 printk(KERN_ERR "tdfxfb: Can't reserve regbase\n"); 1220 printk(KERN_ERR "tdfxfb: Can't reserve regbase\n");
1220 goto out_err; 1221 goto out_err;
1221 } 1222 }
1222 1223
1223 default_par->regbase_virt = 1224 default_par->regbase_virt =
1224 ioremap_nocache(tdfx_fix.mmio_start, tdfx_fix.mmio_len); 1225 ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len);
1225 if (!default_par->regbase_virt) { 1226 if (!default_par->regbase_virt) {
1226 printk(KERN_ERR "fb: Can't remap %s register area.\n", 1227 printk(KERN_ERR "fb: Can't remap %s register area.\n",
1227 tdfx_fix.id); 1228 info->fix.id);
1228 goto out_err_regbase; 1229 goto out_err_regbase;
1229 } 1230 }
1230 1231
1231 tdfx_fix.smem_start = pci_resource_start(pdev, 1); 1232 info->fix.smem_start = pci_resource_start(pdev, 1);
1232 tdfx_fix.smem_len = do_lfb_size(default_par, pdev->device); 1233 info->fix.smem_len = do_lfb_size(default_par, pdev->device);
1233 if (!tdfx_fix.smem_len) { 1234 if (!info->fix.smem_len) {
1234 printk(KERN_ERR "fb: Can't count %s memory.\n", tdfx_fix.id); 1235 printk(KERN_ERR "fb: Can't count %s memory.\n", info->fix.id);
1235 goto out_err_regbase; 1236 goto out_err_regbase;
1236 } 1237 }
1237 1238
1238 if (!request_mem_region(tdfx_fix.smem_start, 1239 if (!request_mem_region(info->fix.smem_start,
1239 pci_resource_len(pdev, 1), "tdfx smem")) { 1240 pci_resource_len(pdev, 1), "tdfx smem")) {
1240 printk(KERN_ERR "tdfxfb: Can't reserve smem\n"); 1241 printk(KERN_ERR "tdfxfb: Can't reserve smem\n");
1241 goto out_err_regbase; 1242 goto out_err_regbase;
1242 } 1243 }
1243 1244
1244 info->screen_base = ioremap_nocache(tdfx_fix.smem_start, 1245 info->screen_base = ioremap_nocache(info->fix.smem_start,
1245 tdfx_fix.smem_len); 1246 info->fix.smem_len);
1246 if (!info->screen_base) { 1247 if (!info->screen_base) {
1247 printk(KERN_ERR "fb: Can't remap %s framebuffer.\n", 1248 printk(KERN_ERR "fb: Can't remap %s framebuffer.\n",
1248 tdfx_fix.id); 1249 info->fix.id);
1249 goto out_err_screenbase; 1250 goto out_err_screenbase;
1250 } 1251 }
1251 1252
@@ -1257,20 +1258,19 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev,
1257 goto out_err_screenbase; 1258 goto out_err_screenbase;
1258 } 1259 }
1259 1260
1260 printk(KERN_INFO "fb: %s memory = %dK\n", tdfx_fix.id, 1261 printk(KERN_INFO "fb: %s memory = %dK\n", info->fix.id,
1261 tdfx_fix.smem_len >> 10); 1262 info->fix.smem_len >> 10);
1262 1263
1263 default_par->mtrr_handle = -1; 1264 default_par->mtrr_handle = -1;
1264 if (!nomtrr) 1265 if (!nomtrr)
1265 default_par->mtrr_handle = 1266 default_par->mtrr_handle =
1266 mtrr_add(tdfx_fix.smem_start, tdfx_fix.smem_len, 1267 mtrr_add(info->fix.smem_start, info->fix.smem_len,
1267 MTRR_TYPE_WRCOMB, 1); 1268 MTRR_TYPE_WRCOMB, 1);
1268 1269
1269 tdfx_fix.ypanstep = nopan ? 0 : 1; 1270 info->fix.ypanstep = nopan ? 0 : 1;
1270 tdfx_fix.ywrapstep = nowrap ? 0 : 1; 1271 info->fix.ywrapstep = nowrap ? 0 : 1;
1271 1272
1272 info->fbops = &tdfxfb_ops; 1273 info->fbops = &tdfxfb_ops;
1273 info->fix = tdfx_fix;
1274 info->pseudo_palette = default_par->palette; 1274 info->pseudo_palette = default_par->palette;
1275 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; 1275 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
1276#ifdef CONFIG_FB_3DFX_ACCEL 1276#ifdef CONFIG_FB_3DFX_ACCEL
@@ -1323,14 +1323,14 @@ out_err_iobase:
1323out_err_screenbase: 1323out_err_screenbase:
1324 if (info->screen_base) 1324 if (info->screen_base)
1325 iounmap(info->screen_base); 1325 iounmap(info->screen_base);
1326 release_mem_region(tdfx_fix.smem_start, pci_resource_len(pdev, 1)); 1326 release_mem_region(info->fix.smem_start, pci_resource_len(pdev, 1));
1327out_err_regbase: 1327out_err_regbase:
1328 /* 1328 /*
1329 * Cleanup after anything that was remapped/allocated. 1329 * Cleanup after anything that was remapped/allocated.
1330 */ 1330 */
1331 if (default_par->regbase_virt) 1331 if (default_par->regbase_virt)
1332 iounmap(default_par->regbase_virt); 1332 iounmap(default_par->regbase_virt);
1333 release_mem_region(tdfx_fix.mmio_start, tdfx_fix.mmio_len); 1333 release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
1334out_err: 1334out_err:
1335 framebuffer_release(info); 1335 framebuffer_release(info);
1336 return -ENXIO; 1336 return -ENXIO;
diff --git a/drivers/video/tmiofb.c b/drivers/video/tmiofb.c
new file mode 100644
index 000000000000..2a380011e9ba
--- /dev/null
+++ b/drivers/video/tmiofb.c
@@ -0,0 +1,1050 @@
1/*
2 * Frame Buffer Device for Toshiba Mobile IO(TMIO) controller
3 *
4 * Copyright(C) 2005-2006 Chris Humbert
5 * Copyright(C) 2005 Dirk Opfer
6 * Copytight(C) 2007,2008 Dmitry Baryshkov
7 *
8 * Based on:
9 * drivers/video/w100fb.c
10 * code written by Sharp/Lineo for 2.4 kernels
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2
14 * as published by the Free Software Foundation;
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 */
21
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/platform_device.h>
25#include <linux/fb.h>
26#include <linux/interrupt.h>
27#include <linux/delay.h>
28/* Why should fb driver call console functions? because acquire_console_sem() */
29#include <linux/console.h>
30#include <linux/mfd/core.h>
31#include <linux/mfd/tmio.h>
32#include <linux/uaccess.h>
33
34/*
35 * accelerator commands
36 */
37#define TMIOFB_ACC_CSADR(x) (0x00000000 | ((x) & 0x001ffffe))
38#define TMIOFB_ACC_CHPIX(x) (0x01000000 | ((x) & 0x000003ff))
39#define TMIOFB_ACC_CVPIX(x) (0x02000000 | ((x) & 0x000003ff))
40#define TMIOFB_ACC_PSADR(x) (0x03000000 | ((x) & 0x00fffffe))
41#define TMIOFB_ACC_PHPIX(x) (0x04000000 | ((x) & 0x000003ff))
42#define TMIOFB_ACC_PVPIX(x) (0x05000000 | ((x) & 0x000003ff))
43#define TMIOFB_ACC_PHOFS(x) (0x06000000 | ((x) & 0x000003ff))
44#define TMIOFB_ACC_PVOFS(x) (0x07000000 | ((x) & 0x000003ff))
45#define TMIOFB_ACC_POADR(x) (0x08000000 | ((x) & 0x00fffffe))
46#define TMIOFB_ACC_RSTR(x) (0x09000000 | ((x) & 0x000000ff))
47#define TMIOFB_ACC_TCLOR(x) (0x0A000000 | ((x) & 0x0000ffff))
48#define TMIOFB_ACC_FILL(x) (0x0B000000 | ((x) & 0x0000ffff))
49#define TMIOFB_ACC_DSADR(x) (0x0C000000 | ((x) & 0x00fffffe))
50#define TMIOFB_ACC_SSADR(x) (0x0D000000 | ((x) & 0x00fffffe))
51#define TMIOFB_ACC_DHPIX(x) (0x0E000000 | ((x) & 0x000003ff))
52#define TMIOFB_ACC_DVPIX(x) (0x0F000000 | ((x) & 0x000003ff))
53#define TMIOFB_ACC_SHPIX(x) (0x10000000 | ((x) & 0x000003ff))
54#define TMIOFB_ACC_SVPIX(x) (0x11000000 | ((x) & 0x000003ff))
55#define TMIOFB_ACC_LBINI(x) (0x12000000 | ((x) & 0x0000ffff))
56#define TMIOFB_ACC_LBK2(x) (0x13000000 | ((x) & 0x0000ffff))
57#define TMIOFB_ACC_SHBINI(x) (0x14000000 | ((x) & 0x0000ffff))
58#define TMIOFB_ACC_SHBK2(x) (0x15000000 | ((x) & 0x0000ffff))
59#define TMIOFB_ACC_SVBINI(x) (0x16000000 | ((x) & 0x0000ffff))
60#define TMIOFB_ACC_SVBK2(x) (0x17000000 | ((x) & 0x0000ffff))
61
62#define TMIOFB_ACC_CMGO 0x20000000
63#define TMIOFB_ACC_CMGO_CEND 0x00000001
64#define TMIOFB_ACC_CMGO_INT 0x00000002
65#define TMIOFB_ACC_CMGO_CMOD 0x00000010
66#define TMIOFB_ACC_CMGO_CDVRV 0x00000020
67#define TMIOFB_ACC_CMGO_CDHRV 0x00000040
68#define TMIOFB_ACC_CMGO_RUND 0x00008000
69#define TMIOFB_ACC_SCGO 0x21000000
70#define TMIOFB_ACC_SCGO_CEND 0x00000001
71#define TMIOFB_ACC_SCGO_INT 0x00000002
72#define TMIOFB_ACC_SCGO_ROP3 0x00000004
73#define TMIOFB_ACC_SCGO_TRNS 0x00000008
74#define TMIOFB_ACC_SCGO_DVRV 0x00000010
75#define TMIOFB_ACC_SCGO_DHRV 0x00000020
76#define TMIOFB_ACC_SCGO_SVRV 0x00000040
77#define TMIOFB_ACC_SCGO_SHRV 0x00000080
78#define TMIOFB_ACC_SCGO_DSTXY 0x00008000
79#define TMIOFB_ACC_SBGO 0x22000000
80#define TMIOFB_ACC_SBGO_CEND 0x00000001
81#define TMIOFB_ACC_SBGO_INT 0x00000002
82#define TMIOFB_ACC_SBGO_DVRV 0x00000010
83#define TMIOFB_ACC_SBGO_DHRV 0x00000020
84#define TMIOFB_ACC_SBGO_SVRV 0x00000040
85#define TMIOFB_ACC_SBGO_SHRV 0x00000080
86#define TMIOFB_ACC_SBGO_SBMD 0x00000100
87#define TMIOFB_ACC_FLGO 0x23000000
88#define TMIOFB_ACC_FLGO_CEND 0x00000001
89#define TMIOFB_ACC_FLGO_INT 0x00000002
90#define TMIOFB_ACC_FLGO_ROP3 0x00000004
91#define TMIOFB_ACC_LDGO 0x24000000
92#define TMIOFB_ACC_LDGO_CEND 0x00000001
93#define TMIOFB_ACC_LDGO_INT 0x00000002
94#define TMIOFB_ACC_LDGO_ROP3 0x00000004
95#define TMIOFB_ACC_LDGO_ENDPX 0x00000008
96#define TMIOFB_ACC_LDGO_LVRV 0x00000010
97#define TMIOFB_ACC_LDGO_LHRV 0x00000020
98#define TMIOFB_ACC_LDGO_LDMOD 0x00000040
99
100/* a FIFO is always allocated, even if acceleration is not used */
101#define TMIOFB_FIFO_SIZE 512
102
103/*
104 * LCD Host Controller Configuration Register
105 *
106 * This iomem area supports only 16-bit IO.
107 */
108#define CCR_CMD 0x04 /* Command */
109#define CCR_REVID 0x08 /* Revision ID */
110#define CCR_BASEL 0x10 /* LCD Control Reg Base Addr Low */
111#define CCR_BASEH 0x12 /* LCD Control Reg Base Addr High */
112#define CCR_UGCC 0x40 /* Unified Gated Clock Control */
113#define CCR_GCC 0x42 /* Gated Clock Control */
114#define CCR_USC 0x50 /* Unified Software Clear */
115#define CCR_VRAMRTC 0x60 /* VRAM Timing Control */
116 /* 0x61 VRAM Refresh Control */
117#define CCR_VRAMSAC 0x62 /* VRAM Access Control */
118 /* 0x63 VRAM Status */
119#define CCR_VRAMBC 0x64 /* VRAM Block Control */
120
121/*
122 * LCD Control Register
123 *
124 * This iomem area supports only 16-bit IO.
125 */
126#define LCR_UIS 0x000 /* Unified Interrupt Status */
127#define LCR_VHPN 0x008 /* VRAM Horizontal Pixel Number */
128#define LCR_CFSAL 0x00a /* Command FIFO Start Address Low */
129#define LCR_CFSAH 0x00c /* Command FIFO Start Address High */
130#define LCR_CFS 0x00e /* Command FIFO Size */
131#define LCR_CFWS 0x010 /* Command FIFO Writeable Size */
132#define LCR_BBIE 0x012 /* BitBLT Interrupt Enable */
133#define LCR_BBISC 0x014 /* BitBLT Interrupt Status and Clear */
134#define LCR_CCS 0x016 /* Command Count Status */
135#define LCR_BBES 0x018 /* BitBLT Execution Status */
136#define LCR_CMDL 0x01c /* Command Low */
137#define LCR_CMDH 0x01e /* Command High */
138#define LCR_CFC 0x022 /* Command FIFO Clear */
139#define LCR_CCIFC 0x024 /* CMOS Camera IF Control */
140#define LCR_HWT 0x026 /* Hardware Test */
141#define LCR_LCDCCRC 0x100 /* LCDC Clock and Reset Control */
142#define LCR_LCDCC 0x102 /* LCDC Control */
143#define LCR_LCDCOPC 0x104 /* LCDC Output Pin Control */
144#define LCR_LCDIS 0x108 /* LCD Interrupt Status */
145#define LCR_LCDIM 0x10a /* LCD Interrupt Mask */
146#define LCR_LCDIE 0x10c /* LCD Interrupt Enable */
147#define LCR_GDSAL 0x122 /* Graphics Display Start Address Low */
148#define LCR_GDSAH 0x124 /* Graphics Display Start Address High */
149#define LCR_VHPCL 0x12a /* VRAM Horizontal Pixel Count Low */
150#define LCR_VHPCH 0x12c /* VRAM Horizontal Pixel Count High */
151#define LCR_GM 0x12e /* Graphic Mode(VRAM access enable) */
152#define LCR_HT 0x140 /* Horizontal Total */
153#define LCR_HDS 0x142 /* Horizontal Display Start */
154#define LCR_HSS 0x144 /* H-Sync Start */
155#define LCR_HSE 0x146 /* H-Sync End */
156#define LCR_HNP 0x14c /* Horizontal Number of Pixels */
157#define LCR_VT 0x150 /* Vertical Total */
158#define LCR_VDS 0x152 /* Vertical Display Start */
159#define LCR_VSS 0x154 /* V-Sync Start */
160#define LCR_VSE 0x156 /* V-Sync End */
161#define LCR_CDLN 0x160 /* Current Display Line Number */
162#define LCR_ILN 0x162 /* Interrupt Line Number */
163#define LCR_SP 0x164 /* Sync Polarity */
164#define LCR_MISC 0x166 /* MISC(RGB565 mode) */
165#define LCR_VIHSS 0x16a /* Video Interface H-Sync Start */
166#define LCR_VIVS 0x16c /* Video Interface Vertical Start */
167#define LCR_VIVE 0x16e /* Video Interface Vertical End */
168#define LCR_VIVSS 0x170 /* Video Interface V-Sync Start */
169#define LCR_VCCIS 0x17e /* Video / CMOS Camera Interface Select */
170#define LCR_VIDWSAL 0x180 /* VI Data Write Start Address Low */
171#define LCR_VIDWSAH 0x182 /* VI Data Write Start Address High */
172#define LCR_VIDRSAL 0x184 /* VI Data Read Start Address Low */
173#define LCR_VIDRSAH 0x186 /* VI Data Read Start Address High */
174#define LCR_VIPDDST 0x188 /* VI Picture Data Display Start Timing */
175#define LCR_VIPDDET 0x186 /* VI Picture Data Display End Timing */
176#define LCR_VIE 0x18c /* Video Interface Enable */
177#define LCR_VCS 0x18e /* Video/Camera Select */
178#define LCR_VPHWC 0x194 /* Video Picture Horizontal Wait Count */
179#define LCR_VPHS 0x196 /* Video Picture Horizontal Size */
180#define LCR_VPVWC 0x198 /* Video Picture Vertical Wait Count */
181#define LCR_VPVS 0x19a /* Video Picture Vertical Size */
182#define LCR_PLHPIX 0x1a0 /* PLHPIX */
183#define LCR_XS 0x1a2 /* XStart */
184#define LCR_XCKHW 0x1a4 /* XCK High Width */
185#define LCR_STHS 0x1a8 /* STH Start */
186#define LCR_VT2 0x1aa /* Vertical Total */
187#define LCR_YCKSW 0x1ac /* YCK Start Wait */
188#define LCR_YSTS 0x1ae /* YST Start */
189#define LCR_PPOLS 0x1b0 /* #PPOL Start */
190#define LCR_PRECW 0x1b2 /* PREC Width */
191#define LCR_VCLKHW 0x1b4 /* VCLK High Width */
192#define LCR_OC 0x1b6 /* Output Control */
193
194static char *mode_option __devinitdata;
195
196struct tmiofb_par {
197 u32 pseudo_palette[16];
198
199#ifdef CONFIG_FB_TMIO_ACCELL
200 wait_queue_head_t wait_acc;
201 bool use_polling;
202#endif
203
204 void __iomem *ccr;
205 void __iomem *lcr;
206};
207
208/*--------------------------------------------------------------------------*/
209
210/*
211 * reasons for an interrupt:
212 * uis bbisc lcdis
213 * 0100 0001 accelerator command completed
214 * 2000 0001 vsync start
215 * 2000 0002 display start
216 * 2000 0004 line number match(0x1ff mask???)
217 */
218static irqreturn_t tmiofb_irq(int irq, void *__info)
219{
220 struct fb_info *info = __info;
221 struct tmiofb_par *par = info->par;
222 unsigned int bbisc = tmio_ioread16(par->lcr + LCR_BBISC);
223
224
225 /*
226 * We were in polling mode and now we got correct irq.
227 * Switch back to IRQ-based sync of command FIFO
228 */
229 if (unlikely(par->use_polling && irq != -1)) {
230 printk(KERN_INFO "tmiofb: switching to waitq\n");
231 par->use_polling = false;
232 }
233
234 tmio_iowrite16(bbisc, par->lcr + LCR_BBISC);
235
236#ifdef CONFIG_FB_TMIO_ACCELL
237 if (bbisc & 1)
238 wake_up(&par->wait_acc);
239#endif
240
241 return IRQ_HANDLED;
242}
243
244
245/*--------------------------------------------------------------------------*/
246
247
248/*
249 * Turns off the LCD controller and LCD host controller.
250 */
251static int tmiofb_hw_stop(struct platform_device *dev)
252{
253 struct mfd_cell *cell = dev->dev.platform_data;
254 struct tmio_fb_data *data = cell->driver_data;
255 struct fb_info *info = platform_get_drvdata(dev);
256 struct tmiofb_par *par = info->par;
257
258 tmio_iowrite16(0, par->ccr + CCR_UGCC);
259 tmio_iowrite16(0, par->lcr + LCR_GM);
260 data->lcd_set_power(dev, 0);
261 tmio_iowrite16(0x0010, par->lcr + LCR_LCDCCRC);
262
263 return 0;
264}
265
266/*
267 * Initializes the LCD host controller.
268 */
269static int tmiofb_hw_init(struct platform_device *dev)
270{
271 struct mfd_cell *cell = dev->dev.platform_data;
272 struct fb_info *info = platform_get_drvdata(dev);
273 struct tmiofb_par *par = info->par;
274 const struct resource *nlcr = &cell->resources[0];
275 const struct resource *vram = &cell->resources[2];
276 unsigned long base;
277
278 if (nlcr == NULL || vram == NULL)
279 return -EINVAL;
280
281 base = nlcr->start;
282
283 tmio_iowrite16(0x003a, par->ccr + CCR_UGCC);
284 tmio_iowrite16(0x003a, par->ccr + CCR_GCC);
285 tmio_iowrite16(0x3f00, par->ccr + CCR_USC);
286
287 msleep(2); /* wait for device to settle */
288
289 tmio_iowrite16(0x0000, par->ccr + CCR_USC);
290 tmio_iowrite16(base >> 16, par->ccr + CCR_BASEH);
291 tmio_iowrite16(base, par->ccr + CCR_BASEL);
292 tmio_iowrite16(0x0002, par->ccr + CCR_CMD); /* base address enable */
293 tmio_iowrite16(0x40a8, par->ccr + CCR_VRAMRTC); /* VRAMRC, VRAMTC */
294 tmio_iowrite16(0x0018, par->ccr + CCR_VRAMSAC); /* VRAMSTS, VRAMAC */
295 tmio_iowrite16(0x0002, par->ccr + CCR_VRAMBC);
296 msleep(2); /* wait for device to settle */
297 tmio_iowrite16(0x000b, par->ccr + CCR_VRAMBC);
298
299 base = vram->start + info->screen_size;
300 tmio_iowrite16(base >> 16, par->lcr + LCR_CFSAH);
301 tmio_iowrite16(base, par->lcr + LCR_CFSAL);
302 tmio_iowrite16(TMIOFB_FIFO_SIZE - 1, par->lcr + LCR_CFS);
303 tmio_iowrite16(1, par->lcr + LCR_CFC);
304 tmio_iowrite16(1, par->lcr + LCR_BBIE);
305 tmio_iowrite16(0, par->lcr + LCR_CFWS);
306
307 return 0;
308}
309
310/*
311 * Sets the LCD controller's output resolution and pixel clock
312 */
313static void tmiofb_hw_mode(struct platform_device *dev)
314{
315 struct mfd_cell *cell = dev->dev.platform_data;
316 struct tmio_fb_data *data = cell->driver_data;
317 struct fb_info *info = platform_get_drvdata(dev);
318 struct fb_videomode *mode = info->mode;
319 struct tmiofb_par *par = info->par;
320 unsigned int i;
321
322 tmio_iowrite16(0, par->lcr + LCR_GM);
323 data->lcd_set_power(dev, 0);
324 tmio_iowrite16(0x0010, par->lcr + LCR_LCDCCRC);
325 data->lcd_mode(dev, mode);
326 data->lcd_set_power(dev, 1);
327
328 tmio_iowrite16(info->fix.line_length, par->lcr + LCR_VHPN);
329 tmio_iowrite16(0, par->lcr + LCR_GDSAH);
330 tmio_iowrite16(0, par->lcr + LCR_GDSAL);
331 tmio_iowrite16(info->fix.line_length >> 16, par->lcr + LCR_VHPCH);
332 tmio_iowrite16(info->fix.line_length, par->lcr + LCR_VHPCL);
333 tmio_iowrite16(i = 0, par->lcr + LCR_HSS);
334 tmio_iowrite16(i += mode->hsync_len, par->lcr + LCR_HSE);
335 tmio_iowrite16(i += mode->left_margin, par->lcr + LCR_HDS);
336 tmio_iowrite16(i += mode->xres + mode->right_margin, par->lcr + LCR_HT);
337 tmio_iowrite16(mode->xres, par->lcr + LCR_HNP);
338 tmio_iowrite16(i = 0, par->lcr + LCR_VSS);
339 tmio_iowrite16(i += mode->vsync_len, par->lcr + LCR_VSE);
340 tmio_iowrite16(i += mode->upper_margin, par->lcr + LCR_VDS);
341 tmio_iowrite16(i += mode->yres, par->lcr + LCR_ILN);
342 tmio_iowrite16(i += mode->lower_margin, par->lcr + LCR_VT);
343 tmio_iowrite16(3, par->lcr + LCR_MISC); /* RGB565 mode */
344 tmio_iowrite16(1, par->lcr + LCR_GM); /* VRAM enable */
345 tmio_iowrite16(0x4007, par->lcr + LCR_LCDCC);
346 tmio_iowrite16(3, par->lcr + LCR_SP); /* sync polarity */
347
348 tmio_iowrite16(0x0010, par->lcr + LCR_LCDCCRC);
349 msleep(5); /* wait for device to settle */
350 tmio_iowrite16(0x0014, par->lcr + LCR_LCDCCRC); /* STOP_CKP */
351 msleep(5); /* wait for device to settle */
352 tmio_iowrite16(0x0015, par->lcr + LCR_LCDCCRC); /* STOP_CKP|SOFT_RESET*/
353 tmio_iowrite16(0xfffa, par->lcr + LCR_VCS);
354}
355
356/*--------------------------------------------------------------------------*/
357
358#ifdef CONFIG_FB_TMIO_ACCELL
359static int __must_check
360tmiofb_acc_wait(struct fb_info *info, unsigned int ccs)
361{
362 struct tmiofb_par *par = info->par;
363 /*
364 * This code can be called whith interrupts disabled.
365 * So instead of relaying on irq to trigger the event,
366 * poll the state till the necessary command is executed.
367 */
368 if (irqs_disabled() || par->use_polling) {
369 int i = 0;
370 while (tmio_ioread16(par->lcr + LCR_CCS) > ccs) {
371 udelay(1);
372 i++;
373 if (i > 10000) {
374 pr_err("tmiofb: timeout waiting for %d\n",
375 ccs);
376 return -ETIMEDOUT;
377 }
378 tmiofb_irq(-1, info);
379 }
380 } else {
381 if (!wait_event_interruptible_timeout(par->wait_acc,
382 tmio_ioread16(par->lcr + LCR_CCS) <= ccs,
383 1000)) {
384 pr_err("tmiofb: timeout waiting for %d\n", ccs);
385 return -ETIMEDOUT;
386 }
387 }
388
389 return 0;
390}
391
392/*
393 * Writes an accelerator command to the accelerator's FIFO.
394 */
395static int
396tmiofb_acc_write(struct fb_info *info, const u32 *cmd, unsigned int count)
397{
398 struct tmiofb_par *par = info->par;
399 int ret;
400
401 ret = tmiofb_acc_wait(info, TMIOFB_FIFO_SIZE - count);
402 if (ret)
403 return ret;
404
405 for (; count; count--, cmd++) {
406 tmio_iowrite16(*cmd >> 16, par->lcr + LCR_CMDH);
407 tmio_iowrite16(*cmd, par->lcr + LCR_CMDL);
408 }
409
410 return ret;
411}
412
413/*
414 * Wait for the accelerator to finish its operations before writing
415 * to the framebuffer for consistent display output.
416 */
417static int tmiofb_sync(struct fb_info *fbi)
418{
419 struct tmiofb_par *par = fbi->par;
420
421 int ret;
422 int i = 0;
423
424 ret = tmiofb_acc_wait(fbi, 0);
425
426 while (tmio_ioread16(par->lcr + LCR_BBES) & 2) { /* blit active */
427 udelay(1);
428 i++ ;
429 if (i > 10000) {
430 printk(KERN_ERR "timeout waiting for blit to end!\n");
431 return -ETIMEDOUT;
432 }
433 }
434
435 return ret;
436}
437
438static void
439tmiofb_fillrect(struct fb_info *fbi, const struct fb_fillrect *rect)
440{
441 const u32 cmd[] = {
442 TMIOFB_ACC_DSADR((rect->dy * fbi->mode->xres + rect->dx) * 2),
443 TMIOFB_ACC_DHPIX(rect->width - 1),
444 TMIOFB_ACC_DVPIX(rect->height - 1),
445 TMIOFB_ACC_FILL(rect->color),
446 TMIOFB_ACC_FLGO,
447 };
448
449 if (fbi->state != FBINFO_STATE_RUNNING ||
450 fbi->flags & FBINFO_HWACCEL_DISABLED) {
451 cfb_fillrect(fbi, rect);
452 return;
453 }
454
455 tmiofb_acc_write(fbi, cmd, ARRAY_SIZE(cmd));
456}
457
458static void
459tmiofb_copyarea(struct fb_info *fbi, const struct fb_copyarea *area)
460{
461 const u32 cmd[] = {
462 TMIOFB_ACC_DSADR((area->dy * fbi->mode->xres + area->dx) * 2),
463 TMIOFB_ACC_DHPIX(area->width - 1),
464 TMIOFB_ACC_DVPIX(area->height - 1),
465 TMIOFB_ACC_SSADR((area->sy * fbi->mode->xres + area->sx) * 2),
466 TMIOFB_ACC_SCGO,
467 };
468
469 if (fbi->state != FBINFO_STATE_RUNNING ||
470 fbi->flags & FBINFO_HWACCEL_DISABLED) {
471 cfb_copyarea(fbi, area);
472 return;
473 }
474
475 tmiofb_acc_write(fbi, cmd, ARRAY_SIZE(cmd));
476}
477#endif
478
479static void tmiofb_clearscreen(struct fb_info *info)
480{
481 const struct fb_fillrect rect = {
482 .dx = 0,
483 .dy = 0,
484 .width = info->mode->xres,
485 .height = info->mode->yres,
486 .color = 0,
487 .rop = ROP_COPY,
488 };
489
490 info->fbops->fb_fillrect(info, &rect);
491}
492
493static int tmiofb_vblank(struct fb_info *fbi, struct fb_vblank *vblank)
494{
495 struct tmiofb_par *par = fbi->par;
496 struct fb_videomode *mode = fbi->mode;
497 unsigned int vcount = tmio_ioread16(par->lcr + LCR_CDLN);
498 unsigned int vds = mode->vsync_len + mode->upper_margin;
499
500 vblank->vcount = vcount;
501 vblank->flags = FB_VBLANK_HAVE_VBLANK | FB_VBLANK_HAVE_VCOUNT
502 | FB_VBLANK_HAVE_VSYNC;
503
504 if (vcount < mode->vsync_len)
505 vblank->flags |= FB_VBLANK_VSYNCING;
506
507 if (vcount < vds || vcount > vds + mode->yres)
508 vblank->flags |= FB_VBLANK_VBLANKING;
509
510 return 0;
511}
512
513
514static int tmiofb_ioctl(struct fb_info *fbi,
515 unsigned int cmd, unsigned long arg)
516{
517 switch (cmd) {
518 case FBIOGET_VBLANK: {
519 struct fb_vblank vblank = {0};
520 void __user *argp = (void __user *) arg;
521
522 tmiofb_vblank(fbi, &vblank);
523 if (copy_to_user(argp, &vblank, sizeof vblank))
524 return -EFAULT;
525 return 0;
526 }
527
528#ifdef CONFIG_FB_TMIO_ACCELL
529 case FBIO_TMIO_ACC_SYNC:
530 tmiofb_sync(fbi);
531 return 0;
532
533 case FBIO_TMIO_ACC_WRITE: {
534 u32 __user *argp = (void __user *) arg;
535 u32 len;
536 u32 acc[16];
537
538 if (get_user(len, argp))
539 return -EFAULT;
540 if (len > ARRAY_SIZE(acc))
541 return -EINVAL;
542 if (copy_from_user(acc, argp + 1, sizeof(u32) * len))
543 return -EFAULT;
544
545 return tmiofb_acc_write(fbi, acc, len);
546 }
547#endif
548 }
549
550 return -ENOTTY;
551}
552
553/*--------------------------------------------------------------------------*/
554
555/* Select the smallest mode that allows the desired resolution to be
556 * displayed. If desired, the x and y parameters can be rounded up to
557 * match the selected mode.
558 */
559static struct fb_videomode *
560tmiofb_find_mode(struct fb_info *info, struct fb_var_screeninfo *var)
561{
562 struct mfd_cell *cell =
563 info->device->platform_data;
564 struct tmio_fb_data *data = cell->driver_data;
565 struct fb_videomode *best = NULL;
566 int i;
567
568 for (i = 0; i < data->num_modes; i++) {
569 struct fb_videomode *mode = data->modes + i;
570
571 if (mode->xres >= var->xres && mode->yres >= var->yres
572 && (!best || (mode->xres < best->xres
573 && mode->yres < best->yres)))
574 best = mode;
575 }
576
577 return best;
578}
579
580static int tmiofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
581{
582
583 struct fb_videomode *mode;
584 struct mfd_cell *cell =
585 info->device->platform_data;
586 struct tmio_fb_data *data = cell->driver_data;
587
588 mode = tmiofb_find_mode(info, var);
589 if (!mode || var->bits_per_pixel > 16)
590 return -EINVAL;
591
592 fb_videomode_to_var(var, mode);
593
594 var->xres_virtual = mode->xres;
595 var->yres_virtual = info->screen_size / (mode->xres * 2);
596
597 if (var->yres_virtual < var->yres)
598 return -EINVAL;
599
600 var->xoffset = 0;
601 var->yoffset = 0;
602 var->bits_per_pixel = 16;
603 var->grayscale = 0;
604 var->red.offset = 11;
605 var->red.length = 5;
606 var->green.offset = 5;
607 var->green.length = 6;
608 var->blue.offset = 0;
609 var->blue.length = 5;
610 var->transp.offset = 0;
611 var->transp.length = 0;
612 var->nonstd = 0;
613 var->height = data->height; /* mm */
614 var->width = data->width; /* mm */
615 var->rotate = 0;
616 return 0;
617}
618
619static int tmiofb_set_par(struct fb_info *info)
620{
621 struct fb_var_screeninfo *var = &info->var;
622 struct fb_videomode *mode;
623
624 mode = tmiofb_find_mode(info, var);
625 if (!mode)
626 return -EINVAL;
627
628 info->mode = mode;
629 info->fix.line_length = info->mode->xres *
630 var->bits_per_pixel / 8;
631
632 tmiofb_hw_mode(to_platform_device(info->device));
633 tmiofb_clearscreen(info);
634 return 0;
635}
636
637static int tmiofb_setcolreg(unsigned regno, unsigned red, unsigned green,
638 unsigned blue, unsigned transp,
639 struct fb_info *info)
640{
641 struct tmiofb_par *par = info->par;
642
643 if (regno < ARRAY_SIZE(par->pseudo_palette)) {
644 par->pseudo_palette[regno] =
645 ((red & 0xf800)) |
646 ((green & 0xfc00) >> 5) |
647 ((blue & 0xf800) >> 11);
648 return 0;
649 }
650
651 return -EINVAL;
652}
653
654static int tmiofb_blank(int blank, struct fb_info *info)
655{
656 /*
657 * everything is done in lcd/bl drivers.
658 * this is purely to make sysfs happy and work.
659 */
660 return 0;
661}
662
663static struct fb_ops tmiofb_ops = {
664 .owner = THIS_MODULE,
665
666 .fb_ioctl = tmiofb_ioctl,
667 .fb_check_var = tmiofb_check_var,
668 .fb_set_par = tmiofb_set_par,
669 .fb_setcolreg = tmiofb_setcolreg,
670 .fb_blank = tmiofb_blank,
671 .fb_imageblit = cfb_imageblit,
672#ifdef CONFIG_FB_TMIO_ACCELL
673 .fb_sync = tmiofb_sync,
674 .fb_fillrect = tmiofb_fillrect,
675 .fb_copyarea = tmiofb_copyarea,
676#else
677 .fb_fillrect = cfb_fillrect,
678 .fb_copyarea = cfb_copyarea,
679#endif
680};
681
682/*--------------------------------------------------------------------------*/
683
684static int __devinit tmiofb_probe(struct platform_device *dev)
685{
686 struct mfd_cell *cell = dev->dev.platform_data;
687 struct tmio_fb_data *data = cell->driver_data;
688 struct resource *ccr = platform_get_resource(dev, IORESOURCE_MEM, 1);
689 struct resource *lcr = platform_get_resource(dev, IORESOURCE_MEM, 0);
690 struct resource *vram = platform_get_resource(dev, IORESOURCE_MEM, 2);
691 int irq = platform_get_irq(dev, 0);
692 struct fb_info *info;
693 struct tmiofb_par *par;
694 int retval;
695
696 /*
697 * This is the only way ATM to disable the fb
698 */
699 if (data == NULL) {
700 dev_err(&dev->dev, "NULL platform data!\n");
701 return -EINVAL;
702 }
703
704 info = framebuffer_alloc(sizeof(struct tmiofb_par), &dev->dev);
705
706 if (!info)
707 return -ENOMEM;
708
709 par = info->par;
710
711#ifdef CONFIG_FB_TMIO_ACCELL
712 init_waitqueue_head(&par->wait_acc);
713
714 par->use_polling = true;
715
716 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA
717 | FBINFO_HWACCEL_FILLRECT;
718#else
719 info->flags = FBINFO_DEFAULT;
720#endif
721
722 info->fbops = &tmiofb_ops;
723
724 strcpy(info->fix.id, "tmio-fb");
725 info->fix.smem_start = vram->start;
726 info->fix.smem_len = resource_size(vram);
727 info->fix.type = FB_TYPE_PACKED_PIXELS;
728 info->fix.visual = FB_VISUAL_TRUECOLOR;
729 info->fix.mmio_start = lcr->start;
730 info->fix.mmio_len = resource_size(lcr);
731 info->fix.accel = FB_ACCEL_NONE;
732 info->screen_size = info->fix.smem_len - (4 * TMIOFB_FIFO_SIZE);
733 info->pseudo_palette = par->pseudo_palette;
734
735 par->ccr = ioremap(ccr->start, resource_size(ccr));
736 if (!par->ccr) {
737 retval = -ENOMEM;
738 goto err_ioremap_ccr;
739 }
740
741 par->lcr = ioremap(info->fix.mmio_start, info->fix.mmio_len);
742 if (!par->lcr) {
743 retval = -ENOMEM;
744 goto err_ioremap_lcr;
745 }
746
747 info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
748 if (!info->screen_base) {
749 retval = -ENOMEM;
750 goto err_ioremap_vram;
751 }
752
753 retval = request_irq(irq, &tmiofb_irq, IRQF_DISABLED,
754 dev->dev.bus_id, info);
755
756 if (retval)
757 goto err_request_irq;
758
759 platform_set_drvdata(dev, info);
760
761 retval = fb_find_mode(&info->var, info, mode_option,
762 data->modes, data->num_modes,
763 data->modes, 16);
764 if (!retval) {
765 retval = -EINVAL;
766 goto err_find_mode;
767 }
768
769 if (cell->enable) {
770 retval = cell->enable(dev);
771 if (retval)
772 goto err_enable;
773 }
774
775 retval = tmiofb_hw_init(dev);
776 if (retval)
777 goto err_hw_init;
778
779 fb_videomode_to_modelist(data->modes, data->num_modes,
780 &info->modelist);
781
782 retval = register_framebuffer(info);
783 if (retval < 0)
784 goto err_register_framebuffer;
785
786 printk(KERN_INFO "fb%d: %s frame buffer device\n",
787 info->node, info->fix.id);
788
789 return 0;
790
791err_register_framebuffer:
792/*err_set_par:*/
793 tmiofb_hw_stop(dev);
794err_hw_init:
795 if (cell->disable)
796 cell->disable(dev);
797err_enable:
798err_find_mode:
799 platform_set_drvdata(dev, NULL);
800 free_irq(irq, info);
801err_request_irq:
802 iounmap(info->screen_base);
803err_ioremap_vram:
804 iounmap(par->lcr);
805err_ioremap_lcr:
806 iounmap(par->ccr);
807err_ioremap_ccr:
808 framebuffer_release(info);
809 return retval;
810}
811
812static int __devexit tmiofb_remove(struct platform_device *dev)
813{
814 struct mfd_cell *cell = dev->dev.platform_data;
815 struct fb_info *info = platform_get_drvdata(dev);
816 int irq = platform_get_irq(dev, 0);
817 struct tmiofb_par *par;
818
819 if (info) {
820 par = info->par;
821 unregister_framebuffer(info);
822
823 tmiofb_hw_stop(dev);
824
825 if (cell->disable)
826 cell->disable(dev);
827
828 platform_set_drvdata(dev, NULL);
829
830 free_irq(irq, info);
831
832 iounmap(info->screen_base);
833 iounmap(par->lcr);
834 iounmap(par->ccr);
835
836 framebuffer_release(info);
837 }
838
839 return 0;
840}
841
842#ifdef DEBUG
843static void tmiofb_dump_regs(struct platform_device *dev)
844{
845 struct fb_info *info = platform_get_drvdata(dev);
846 struct tmiofb_par *par = info->par;
847
848 printk(KERN_DEBUG "lhccr:\n");
849#define CCR_PR(n) printk(KERN_DEBUG "\t" #n " = \t%04x\n",\
850 tmio_ioread16(par->ccr + CCR_ ## n));
851 CCR_PR(CMD);
852 CCR_PR(REVID);
853 CCR_PR(BASEL);
854 CCR_PR(BASEH);
855 CCR_PR(UGCC);
856 CCR_PR(GCC);
857 CCR_PR(USC);
858 CCR_PR(VRAMRTC);
859 CCR_PR(VRAMSAC);
860 CCR_PR(VRAMBC);
861#undef CCR_PR
862
863 printk(KERN_DEBUG "lcr: \n");
864#define LCR_PR(n) printk(KERN_DEBUG "\t" #n " = \t%04x\n",\
865 tmio_ioread16(par->lcr + LCR_ ## n));
866 LCR_PR(UIS);
867 LCR_PR(VHPN);
868 LCR_PR(CFSAL);
869 LCR_PR(CFSAH);
870 LCR_PR(CFS);
871 LCR_PR(CFWS);
872 LCR_PR(BBIE);
873 LCR_PR(BBISC);
874 LCR_PR(CCS);
875 LCR_PR(BBES);
876 LCR_PR(CMDL);
877 LCR_PR(CMDH);
878 LCR_PR(CFC);
879 LCR_PR(CCIFC);
880 LCR_PR(HWT);
881 LCR_PR(LCDCCRC);
882 LCR_PR(LCDCC);
883 LCR_PR(LCDCOPC);
884 LCR_PR(LCDIS);
885 LCR_PR(LCDIM);
886 LCR_PR(LCDIE);
887 LCR_PR(GDSAL);
888 LCR_PR(GDSAH);
889 LCR_PR(VHPCL);
890 LCR_PR(VHPCH);
891 LCR_PR(GM);
892 LCR_PR(HT);
893 LCR_PR(HDS);
894 LCR_PR(HSS);
895 LCR_PR(HSE);
896 LCR_PR(HNP);
897 LCR_PR(VT);
898 LCR_PR(VDS);
899 LCR_PR(VSS);
900 LCR_PR(VSE);
901 LCR_PR(CDLN);
902 LCR_PR(ILN);
903 LCR_PR(SP);
904 LCR_PR(MISC);
905 LCR_PR(VIHSS);
906 LCR_PR(VIVS);
907 LCR_PR(VIVE);
908 LCR_PR(VIVSS);
909 LCR_PR(VCCIS);
910 LCR_PR(VIDWSAL);
911 LCR_PR(VIDWSAH);
912 LCR_PR(VIDRSAL);
913 LCR_PR(VIDRSAH);
914 LCR_PR(VIPDDST);
915 LCR_PR(VIPDDET);
916 LCR_PR(VIE);
917 LCR_PR(VCS);
918 LCR_PR(VPHWC);
919 LCR_PR(VPHS);
920 LCR_PR(VPVWC);
921 LCR_PR(VPVS);
922 LCR_PR(PLHPIX);
923 LCR_PR(XS);
924 LCR_PR(XCKHW);
925 LCR_PR(STHS);
926 LCR_PR(VT2);
927 LCR_PR(YCKSW);
928 LCR_PR(YSTS);
929 LCR_PR(PPOLS);
930 LCR_PR(PRECW);
931 LCR_PR(VCLKHW);
932 LCR_PR(OC);
933#undef LCR_PR
934}
935#endif
936
937#ifdef CONFIG_PM
938static int tmiofb_suspend(struct platform_device *dev, pm_message_t state)
939{
940 struct fb_info *info = platform_get_drvdata(dev);
941 struct tmiofb_par *par = info->par;
942 struct mfd_cell *cell = dev->dev.platform_data;
943 int retval = 0;
944
945 acquire_console_sem();
946
947 fb_set_suspend(info, 1);
948
949 if (info->fbops->fb_sync)
950 info->fbops->fb_sync(info);
951
952
953 /*
954 * The fb should be usable even if interrupts are disabled (and they are
955 * during suspend/resume). Switch temporary to forced polling.
956 */
957 printk(KERN_INFO "tmiofb: switching to polling\n");
958 par->use_polling = true;
959 tmiofb_hw_stop(dev);
960
961 if (cell->suspend)
962 retval = cell->suspend(dev);
963
964 release_console_sem();
965
966 return retval;
967}
968
969static int tmiofb_resume(struct platform_device *dev)
970{
971 struct fb_info *info = platform_get_drvdata(dev);
972 struct mfd_cell *cell = dev->dev.platform_data;
973 int retval;
974
975 acquire_console_sem();
976
977 if (cell->resume) {
978 retval = cell->resume(dev);
979 if (retval)
980 goto out;
981 }
982
983 tmiofb_irq(-1, info);
984
985 tmiofb_hw_init(dev);
986
987 tmiofb_hw_mode(dev);
988
989 fb_set_suspend(info, 0);
990out:
991 release_console_sem();
992 return retval;
993}
994#else
995#define tmiofb_suspend NULL
996#define tmiofb_resume NULL
997#endif
998
999static struct platform_driver tmiofb_driver = {
1000 .driver.name = "tmio-fb",
1001 .driver.owner = THIS_MODULE,
1002 .probe = tmiofb_probe,
1003 .remove = __devexit_p(tmiofb_remove),
1004 .suspend = tmiofb_suspend,
1005 .resume = tmiofb_resume,
1006};
1007
1008/*--------------------------------------------------------------------------*/
1009
1010#ifndef MODULE
1011static void __init tmiofb_setup(char *options)
1012{
1013 char *this_opt;
1014
1015 if (!options || !*options)
1016 return;
1017
1018 while ((this_opt = strsep(&options, ",")) != NULL) {
1019 if (!*this_opt)
1020 continue;
1021 /*
1022 * FIXME
1023 */
1024 }
1025}
1026#endif
1027
1028static int __init tmiofb_init(void)
1029{
1030#ifndef MODULE
1031 char *option = NULL;
1032
1033 if (fb_get_options("tmiofb", &option))
1034 return -ENODEV;
1035 tmiofb_setup(option);
1036#endif
1037 return platform_driver_register(&tmiofb_driver);
1038}
1039
1040static void __exit tmiofb_cleanup(void)
1041{
1042 platform_driver_unregister(&tmiofb_driver);
1043}
1044
1045module_init(tmiofb_init);
1046module_exit(tmiofb_cleanup);
1047
1048MODULE_DESCRIPTION("TMIO framebuffer driver");
1049MODULE_AUTHOR("Chris Humbert, Dirk Opfer, Dmitry Baryshkov");
1050MODULE_LICENSE("GPL");
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index 50744229c7a9..6c2d37fdd3b9 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -516,10 +516,12 @@ static int __devinit uvesafb_vbe_getmodes(struct uvesafb_ktask *task,
516 516
517 err = uvesafb_exec(task); 517 err = uvesafb_exec(task);
518 if (err || (task->t.regs.eax & 0xffff) != 0x004f) { 518 if (err || (task->t.regs.eax & 0xffff) != 0x004f) {
519 printk(KERN_ERR "uvesafb: Getting mode info block " 519 printk(KERN_WARNING "uvesafb: Getting mode info block "
520 "for mode 0x%x failed (eax=0x%x, err=%d)\n", 520 "for mode 0x%x failed (eax=0x%x, err=%d)\n",
521 *mode, (u32)task->t.regs.eax, err); 521 *mode, (u32)task->t.regs.eax, err);
522 return -EINVAL; 522 mode++;
523 par->vbe_modes_cnt--;
524 continue;
523 } 525 }
524 526
525 mib = task->buf; 527 mib = task->buf;
@@ -548,7 +550,10 @@ static int __devinit uvesafb_vbe_getmodes(struct uvesafb_ktask *task,
548 mib->depth = mib->bits_per_pixel; 550 mib->depth = mib->bits_per_pixel;
549 } 551 }
550 552
551 return 0; 553 if (par->vbe_modes_cnt > 0)
554 return 0;
555 else
556 return -EINVAL;
552} 557}
553 558
554/* 559/*
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c
index e31bca8a0cb2..5b2938903ac2 100644
--- a/drivers/video/vga16fb.c
+++ b/drivers/video/vga16fb.c
@@ -58,7 +58,6 @@ struct vga16fb_par {
58 unsigned char ClockingMode; /* Seq-Controller:01h */ 58 unsigned char ClockingMode; /* Seq-Controller:01h */
59 } vga_state; 59 } vga_state;
60 struct vgastate state; 60 struct vgastate state;
61 struct mutex open_lock;
62 unsigned int ref_count; 61 unsigned int ref_count;
63 int palette_blanked, vesa_blanked, mode, isVGA; 62 int palette_blanked, vesa_blanked, mode, isVGA;
64 u8 misc, pel_msk, vss, clkdiv; 63 u8 misc, pel_msk, vss, clkdiv;
@@ -286,7 +285,6 @@ static int vga16fb_open(struct fb_info *info, int user)
286{ 285{
287 struct vga16fb_par *par = info->par; 286 struct vga16fb_par *par = info->par;
288 287
289 mutex_lock(&par->open_lock);
290 if (!par->ref_count) { 288 if (!par->ref_count) {
291 memset(&par->state, 0, sizeof(struct vgastate)); 289 memset(&par->state, 0, sizeof(struct vgastate));
292 par->state.flags = VGA_SAVE_FONTS | VGA_SAVE_MODE | 290 par->state.flags = VGA_SAVE_FONTS | VGA_SAVE_MODE |
@@ -294,7 +292,6 @@ static int vga16fb_open(struct fb_info *info, int user)
294 save_vga(&par->state); 292 save_vga(&par->state);
295 } 293 }
296 par->ref_count++; 294 par->ref_count++;
297 mutex_unlock(&par->open_lock);
298 295
299 return 0; 296 return 0;
300} 297}
@@ -303,15 +300,12 @@ static int vga16fb_release(struct fb_info *info, int user)
303{ 300{
304 struct vga16fb_par *par = info->par; 301 struct vga16fb_par *par = info->par;
305 302
306 mutex_lock(&par->open_lock); 303 if (!par->ref_count)
307 if (!par->ref_count) {
308 mutex_unlock(&par->open_lock);
309 return -EINVAL; 304 return -EINVAL;
310 } 305
311 if (par->ref_count == 1) 306 if (par->ref_count == 1)
312 restore_vga(&par->state); 307 restore_vga(&par->state);
313 par->ref_count--; 308 par->ref_count--;
314 mutex_unlock(&par->open_lock);
315 309
316 return 0; 310 return 0;
317} 311}
@@ -1326,7 +1320,6 @@ static int __init vga16fb_probe(struct platform_device *dev)
1326 printk(KERN_INFO "vga16fb: mapped to 0x%p\n", info->screen_base); 1320 printk(KERN_INFO "vga16fb: mapped to 0x%p\n", info->screen_base);
1327 par = info->par; 1321 par = info->par;
1328 1322
1329 mutex_init(&par->open_lock);
1330 par->isVGA = screen_info.orig_video_isVGA; 1323 par->isVGA = screen_info.orig_video_isVGA;
1331 par->palette_blanked = 0; 1324 par->palette_blanked = 0;
1332 par->vesa_blanked = 0; 1325 par->vesa_blanked = 0;
diff --git a/drivers/video/via/Makefile b/drivers/video/via/Makefile
new file mode 100644
index 000000000000..e533b4b6aba4
--- /dev/null
+++ b/drivers/video/via/Makefile
@@ -0,0 +1,7 @@
1#
2# Makefile for the VIA framebuffer driver (for Linux Kernel 2.6)
3#
4
5obj-$(CONFIG_FB_VIA) += viafb.o
6
7viafb-y :=viafbdev.o hw.o iface.o via_i2c.o dvi.o lcd.o ioctl.o accel.o via_utility.o vt1636.o global.o tblDPASetting.o viamode.o tbl1636.o
diff --git a/drivers/video/via/accel.c b/drivers/video/via/accel.c
new file mode 100644
index 000000000000..632523ff1fb7
--- /dev/null
+++ b/drivers/video/via/accel.c
@@ -0,0 +1,279 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
14 * for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21#include "global.h"
22
23void viafb_init_accel(void)
24{
25 viaparinfo->fbmem_free -= CURSOR_SIZE;
26 viaparinfo->cursor_start = viaparinfo->fbmem_free;
27 viaparinfo->fbmem_used += CURSOR_SIZE;
28
29 /* Reverse 8*1024 memory space for cursor image */
30 viaparinfo->fbmem_free -= (CURSOR_SIZE + VQ_SIZE);
31 viaparinfo->VQ_start = viaparinfo->fbmem_free;
32 viaparinfo->VQ_end = viaparinfo->VQ_start + VQ_SIZE - 1;
33 viaparinfo->fbmem_used += (CURSOR_SIZE + VQ_SIZE); }
34
35void viafb_init_2d_engine(void)
36{
37 u32 dwVQStartAddr, dwVQEndAddr;
38 u32 dwVQLen, dwVQStartL, dwVQEndL, dwVQStartEndH;
39
40 /* init 2D engine regs to reset 2D engine */
41 writel(0x0, viaparinfo->io_virt + VIA_REG_GEMODE);
42 writel(0x0, viaparinfo->io_virt + VIA_REG_SRCPOS);
43 writel(0x0, viaparinfo->io_virt + VIA_REG_DSTPOS);
44 writel(0x0, viaparinfo->io_virt + VIA_REG_DIMENSION);
45 writel(0x0, viaparinfo->io_virt + VIA_REG_PATADDR);
46 writel(0x0, viaparinfo->io_virt + VIA_REG_FGCOLOR);
47 writel(0x0, viaparinfo->io_virt + VIA_REG_BGCOLOR);
48 writel(0x0, viaparinfo->io_virt + VIA_REG_CLIPTL);
49 writel(0x0, viaparinfo->io_virt + VIA_REG_CLIPBR);
50 writel(0x0, viaparinfo->io_virt + VIA_REG_OFFSET);
51 writel(0x0, viaparinfo->io_virt + VIA_REG_KEYCONTROL);
52 writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE);
53 writel(0x0, viaparinfo->io_virt + VIA_REG_DSTBASE);
54 writel(0x0, viaparinfo->io_virt + VIA_REG_PITCH);
55 writel(0x0, viaparinfo->io_virt + VIA_REG_MONOPAT1);
56
57 /* Init AGP and VQ regs */
58 switch (viaparinfo->chip_info->gfx_chip_name) {
59 case UNICHROME_K8M890:
60 case UNICHROME_P4M900:
61 writel(0x00100000, viaparinfo->io_virt + VIA_REG_CR_TRANSET);
62 writel(0x680A0000, viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
63 writel(0x02000000, viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
64 break;
65
66 default:
67 writel(0x00100000, viaparinfo->io_virt + VIA_REG_TRANSET);
68 writel(0x00000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
69 writel(0x00333004, viaparinfo->io_virt + VIA_REG_TRANSPACE);
70 writel(0x60000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
71 writel(0x61000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
72 writel(0x62000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
73 writel(0x63000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
74 writel(0x64000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
75 writel(0x7D000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
76
77 writel(0xFE020000, viaparinfo->io_virt + VIA_REG_TRANSET);
78 writel(0x00000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
79 break;
80 }
81 if (viaparinfo->VQ_start != 0) {
82 /* Enable VQ */
83 dwVQStartAddr = viaparinfo->VQ_start;
84 dwVQEndAddr = viaparinfo->VQ_end;
85
86 dwVQStartL = 0x50000000 | (dwVQStartAddr & 0xFFFFFF);
87 dwVQEndL = 0x51000000 | (dwVQEndAddr & 0xFFFFFF);
88 dwVQStartEndH = 0x52000000 |
89 ((dwVQStartAddr & 0xFF000000) >> 24) |
90 ((dwVQEndAddr & 0xFF000000) >> 16);
91 dwVQLen = 0x53000000 | (VQ_SIZE >> 3);
92 switch (viaparinfo->chip_info->gfx_chip_name) {
93 case UNICHROME_K8M890:
94 case UNICHROME_P4M900:
95 dwVQStartL |= 0x20000000;
96 dwVQEndL |= 0x20000000;
97 dwVQStartEndH |= 0x20000000;
98 dwVQLen |= 0x20000000;
99 break;
100 default:
101 break;
102 }
103
104 switch (viaparinfo->chip_info->gfx_chip_name) {
105 case UNICHROME_K8M890:
106 case UNICHROME_P4M900:
107 writel(0x00100000,
108 viaparinfo->io_virt + VIA_REG_CR_TRANSET);
109 writel(dwVQStartEndH,
110 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
111 writel(dwVQStartL,
112 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
113 writel(dwVQEndL,
114 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
115 writel(dwVQLen,
116 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
117 writel(0x74301001,
118 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
119 writel(0x00000000,
120 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
121 break;
122 default:
123 writel(0x00FE0000,
124 viaparinfo->io_virt + VIA_REG_TRANSET);
125 writel(0x080003FE,
126 viaparinfo->io_virt + VIA_REG_TRANSPACE);
127 writel(0x0A00027C,
128 viaparinfo->io_virt + VIA_REG_TRANSPACE);
129 writel(0x0B000260,
130 viaparinfo->io_virt + VIA_REG_TRANSPACE);
131 writel(0x0C000274,
132 viaparinfo->io_virt + VIA_REG_TRANSPACE);
133 writel(0x0D000264,
134 viaparinfo->io_virt + VIA_REG_TRANSPACE);
135 writel(0x0E000000,
136 viaparinfo->io_virt + VIA_REG_TRANSPACE);
137 writel(0x0F000020,
138 viaparinfo->io_virt + VIA_REG_TRANSPACE);
139 writel(0x1000027E,
140 viaparinfo->io_virt + VIA_REG_TRANSPACE);
141 writel(0x110002FE,
142 viaparinfo->io_virt + VIA_REG_TRANSPACE);
143 writel(0x200F0060,
144 viaparinfo->io_virt + VIA_REG_TRANSPACE);
145
146 writel(0x00000006,
147 viaparinfo->io_virt + VIA_REG_TRANSPACE);
148 writel(0x40008C0F,
149 viaparinfo->io_virt + VIA_REG_TRANSPACE);
150 writel(0x44000000,
151 viaparinfo->io_virt + VIA_REG_TRANSPACE);
152 writel(0x45080C04,
153 viaparinfo->io_virt + VIA_REG_TRANSPACE);
154 writel(0x46800408,
155 viaparinfo->io_virt + VIA_REG_TRANSPACE);
156
157 writel(dwVQStartEndH,
158 viaparinfo->io_virt + VIA_REG_TRANSPACE);
159 writel(dwVQStartL,
160 viaparinfo->io_virt + VIA_REG_TRANSPACE);
161 writel(dwVQEndL,
162 viaparinfo->io_virt + VIA_REG_TRANSPACE);
163 writel(dwVQLen,
164 viaparinfo->io_virt + VIA_REG_TRANSPACE);
165 break;
166 }
167 } else {
168 /* Disable VQ */
169 switch (viaparinfo->chip_info->gfx_chip_name) {
170 case UNICHROME_K8M890:
171 case UNICHROME_P4M900:
172 writel(0x00100000,
173 viaparinfo->io_virt + VIA_REG_CR_TRANSET);
174 writel(0x74301000,
175 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
176 break;
177 default:
178 writel(0x00FE0000,
179 viaparinfo->io_virt + VIA_REG_TRANSET);
180 writel(0x00000004,
181 viaparinfo->io_virt + VIA_REG_TRANSPACE);
182 writel(0x40008C0F,
183 viaparinfo->io_virt + VIA_REG_TRANSPACE);
184 writel(0x44000000,
185 viaparinfo->io_virt + VIA_REG_TRANSPACE);
186 writel(0x45080C04,
187 viaparinfo->io_virt + VIA_REG_TRANSPACE);
188 writel(0x46800408,
189 viaparinfo->io_virt + VIA_REG_TRANSPACE);
190 break;
191 }
192 }
193
194 viafb_set_2d_color_depth(viaparinfo->bpp);
195
196 writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE);
197 writel(0x0, viaparinfo->io_virt + VIA_REG_DSTBASE);
198
199 writel(VIA_PITCH_ENABLE |
200 (((viaparinfo->hres *
201 viaparinfo->bpp >> 3) >> 3) | (((viaparinfo->hres *
202 viaparinfo->
203 bpp >> 3) >> 3) << 16)),
204 viaparinfo->io_virt + VIA_REG_PITCH);
205}
206
207void viafb_set_2d_color_depth(int bpp)
208{
209 u32 dwGEMode;
210
211 dwGEMode = readl(viaparinfo->io_virt + 0x04) & 0xFFFFFCFF;
212
213 switch (bpp) {
214 case 16:
215 dwGEMode |= VIA_GEM_16bpp;
216 break;
217 case 32:
218 dwGEMode |= VIA_GEM_32bpp;
219 break;
220 default:
221 dwGEMode |= VIA_GEM_8bpp;
222 break;
223 }
224
225 /* Set BPP and Pitch */
226 writel(dwGEMode, viaparinfo->io_virt + VIA_REG_GEMODE);
227}
228
229void viafb_hw_cursor_init(void)
230{
231 /* Set Cursor Image Base Address */
232 writel(viaparinfo->cursor_start,
233 viaparinfo->io_virt + VIA_REG_CURSOR_MODE);
234 writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_POS);
235 writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_ORG);
236 writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_BG);
237 writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_FG);
238}
239
240void viafb_show_hw_cursor(struct fb_info *info, int Status)
241{
242 u32 temp;
243 u32 iga_path = ((struct viafb_par *)(info->par))->iga_path;
244
245 temp = readl(viaparinfo->io_virt + VIA_REG_CURSOR_MODE);
246 switch (Status) {
247 case HW_Cursor_ON:
248 temp |= 0x1;
249 break;
250 case HW_Cursor_OFF:
251 temp &= 0xFFFFFFFE;
252 break;
253 }
254 switch (iga_path) {
255 case IGA2:
256 temp |= 0x80000000;
257 break;
258 case IGA1:
259 default:
260 temp &= 0x7FFFFFFF;
261 }
262 writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_MODE);
263}
264
265int viafb_wait_engine_idle(void)
266{
267 int loop = 0;
268
269 while (!(readl(viaparinfo->io_virt + VIA_REG_STATUS) &
270 VIA_VR_QUEUE_BUSY) && (loop++ < MAXLOOP))
271 cpu_relax();
272
273 while ((readl(viaparinfo->io_virt + VIA_REG_STATUS) &
274 (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) &&
275 (loop++ < MAXLOOP))
276 cpu_relax();
277
278 return loop >= MAXLOOP;
279}
diff --git a/drivers/video/via/accel.h b/drivers/video/via/accel.h
new file mode 100644
index 000000000000..29bf854e8ccf
--- /dev/null
+++ b/drivers/video/via/accel.h
@@ -0,0 +1,169 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
14 * for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22#ifndef __ACCEL_H__
23#define __ACCEL_H__
24
25#define FB_ACCEL_VIA_UNICHROME 50
26
27/* MMIO Base Address Definition */
28#define MMIO_VGABASE 0x8000
29#define MMIO_CR_READ (MMIO_VGABASE + 0x3D4)
30#define MMIO_CR_WRITE (MMIO_VGABASE + 0x3D5)
31#define MMIO_SR_READ (MMIO_VGABASE + 0x3C4)
32#define MMIO_SR_WRITE (MMIO_VGABASE + 0x3C5)
33
34/* HW Cursor Status Define */
35#define HW_Cursor_ON 0
36#define HW_Cursor_OFF 1
37
38#define CURSOR_SIZE (8 * 1024)
39#define VQ_SIZE (256 * 1024)
40
41#define VIA_MMIO_BLTBASE 0x200000
42#define VIA_MMIO_BLTSIZE 0x200000
43
44/* Defines for 2D registers */
45#define VIA_REG_GECMD 0x000
46#define VIA_REG_GEMODE 0x004
47#define VIA_REG_SRCPOS 0x008
48#define VIA_REG_DSTPOS 0x00C
49/* width and height */
50#define VIA_REG_DIMENSION 0x010
51#define VIA_REG_PATADDR 0x014
52#define VIA_REG_FGCOLOR 0x018
53#define VIA_REG_BGCOLOR 0x01C
54/* top and left of clipping */
55#define VIA_REG_CLIPTL 0x020
56/* bottom and right of clipping */
57#define VIA_REG_CLIPBR 0x024
58#define VIA_REG_OFFSET 0x028
59/* color key control */
60#define VIA_REG_KEYCONTROL 0x02C
61#define VIA_REG_SRCBASE 0x030
62#define VIA_REG_DSTBASE 0x034
63/* pitch of src and dst */
64#define VIA_REG_PITCH 0x038
65#define VIA_REG_MONOPAT0 0x03C
66#define VIA_REG_MONOPAT1 0x040
67/* from 0x100 to 0x1ff */
68#define VIA_REG_COLORPAT 0x100
69
70/* VIA_REG_PITCH(0x38): Pitch Setting */
71#define VIA_PITCH_ENABLE 0x80000000
72
73/* defines for VIA HW cursor registers */
74#define VIA_REG_CURSOR_MODE 0x2D0
75#define VIA_REG_CURSOR_POS 0x2D4
76#define VIA_REG_CURSOR_ORG 0x2D8
77#define VIA_REG_CURSOR_BG 0x2DC
78#define VIA_REG_CURSOR_FG 0x2E0
79
80/* VIA_REG_GEMODE(0x04): GE mode */
81#define VIA_GEM_8bpp 0x00000000
82#define VIA_GEM_16bpp 0x00000100
83#define VIA_GEM_32bpp 0x00000300
84
85/* VIA_REG_GECMD(0x00): 2D Engine Command */
86#define VIA_GEC_NOOP 0x00000000
87#define VIA_GEC_BLT 0x00000001
88#define VIA_GEC_LINE 0x00000005
89
90/* Rotate Command */
91#define VIA_GEC_ROT 0x00000008
92
93#define VIA_GEC_SRC_XY 0x00000000
94#define VIA_GEC_SRC_LINEAR 0x00000010
95#define VIA_GEC_DST_XY 0x00000000
96#define VIA_GEC_DST_LINRAT 0x00000020
97
98#define VIA_GEC_SRC_FB 0x00000000
99#define VIA_GEC_SRC_SYS 0x00000040
100#define VIA_GEC_DST_FB 0x00000000
101#define VIA_GEC_DST_SYS 0x00000080
102
103/* source is mono */
104#define VIA_GEC_SRC_MONO 0x00000100
105/* pattern is mono */
106#define VIA_GEC_PAT_MONO 0x00000200
107/* mono src is opaque */
108#define VIA_GEC_MSRC_OPAQUE 0x00000000
109/* mono src is transparent */
110#define VIA_GEC_MSRC_TRANS 0x00000400
111/* pattern is in frame buffer */
112#define VIA_GEC_PAT_FB 0x00000000
113/* pattern is from reg setting */
114#define VIA_GEC_PAT_REG 0x00000800
115
116#define VIA_GEC_CLIP_DISABLE 0x00000000
117#define VIA_GEC_CLIP_ENABLE 0x00001000
118
119#define VIA_GEC_FIXCOLOR_PAT 0x00002000
120
121#define VIA_GEC_INCX 0x00000000
122#define VIA_GEC_DECY 0x00004000
123#define VIA_GEC_INCY 0x00000000
124#define VIA_GEC_DECX 0x00008000
125/* mono pattern is opaque */
126#define VIA_GEC_MPAT_OPAQUE 0x00000000
127/* mono pattern is transparent */
128#define VIA_GEC_MPAT_TRANS 0x00010000
129
130#define VIA_GEC_MONO_UNPACK 0x00000000
131#define VIA_GEC_MONO_PACK 0x00020000
132#define VIA_GEC_MONO_DWORD 0x00000000
133#define VIA_GEC_MONO_WORD 0x00040000
134#define VIA_GEC_MONO_BYTE 0x00080000
135
136#define VIA_GEC_LASTPIXEL_ON 0x00000000
137#define VIA_GEC_LASTPIXEL_OFF 0x00100000
138#define VIA_GEC_X_MAJOR 0x00000000
139#define VIA_GEC_Y_MAJOR 0x00200000
140#define VIA_GEC_QUICK_START 0x00800000
141
142/* defines for VIA 3D registers */
143#define VIA_REG_STATUS 0x400
144#define VIA_REG_CR_TRANSET 0x41C
145#define VIA_REG_CR_TRANSPACE 0x420
146#define VIA_REG_TRANSET 0x43C
147#define VIA_REG_TRANSPACE 0x440
148
149/* VIA_REG_STATUS(0x400): Engine Status */
150
151/* Command Regulator is busy */
152#define VIA_CMD_RGTR_BUSY 0x00000080
153/* 2D Engine is busy */
154#define VIA_2D_ENG_BUSY 0x00000002
155/* 3D Engine is busy */
156#define VIA_3D_ENG_BUSY 0x00000001
157/* Virtual Queue is busy */
158#define VIA_VR_QUEUE_BUSY 0x00020000
159
160#define MAXLOOP 0xFFFFFF
161
162void viafb_init_accel(void);
163void viafb_init_2d_engine(void);
164void set_2d_color_depth(int);
165void viafb_hw_cursor_init(void);
166void viafb_show_hw_cursor(struct fb_info *info, int Status); int
167viafb_wait_engine_idle(void); void viafb_set_2d_color_depth(int bpp);
168
169#endif /* __ACCEL_H__ */
diff --git a/drivers/video/via/chip.h b/drivers/video/via/chip.h
new file mode 100644
index 000000000000..dde95edc387a
--- /dev/null
+++ b/drivers/video/via/chip.h
@@ -0,0 +1,190 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
14 * for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21#ifndef __CHIP_H__
22#define __CHIP_H__
23
24#include "global.h"
25
26/***************************************/
27/* Definition Graphic Chip Information */
28/***************************************/
29
30#define PCI_VIA_VENDOR_ID 0x1106
31
32/* Define VIA Graphic Chip Name */
33#define UNICHROME_CLE266 1
34#define UNICHROME_CLE266_DID 0x3122
35#define CLE266_REVISION_AX 0x0A
36#define CLE266_REVISION_CX 0x0C
37
38#define UNICHROME_K400 2
39#define UNICHROME_K400_DID 0x7205
40
41#define UNICHROME_K800 3
42#define UNICHROME_K800_DID 0x3108
43
44#define UNICHROME_PM800 4
45#define UNICHROME_PM800_DID 0x3118
46
47#define UNICHROME_CN700 5
48#define UNICHROME_CN700_DID 0x3344
49
50#define UNICHROME_CX700 6
51#define UNICHROME_CX700_DID 0x3157
52#define CX700_REVISION_700 0x0
53#define CX700_REVISION_700M 0x1
54#define CX700_REVISION_700M2 0x2
55
56#define UNICHROME_CN750 7
57#define UNICHROME_CN750_DID 0x3225
58
59#define UNICHROME_K8M890 8
60#define UNICHROME_K8M890_DID 0x3230
61
62#define UNICHROME_P4M890 9
63#define UNICHROME_P4M890_DID 0x3343
64
65#define UNICHROME_P4M900 10
66#define UNICHROME_P4M900_DID 0x3371
67
68#define UNICHROME_VX800 11
69#define UNICHROME_VX800_DID 0x1122
70
71/**************************************************/
72/* Definition TMDS Trasmitter Information */
73/**************************************************/
74
75/* Definition TMDS Trasmitter Index */
76#define NON_TMDS_TRANSMITTER 0x00
77#define VT1632_TMDS 0x01
78#define INTEGRATED_TMDS 0x42
79
80/* Definition TMDS Trasmitter I2C Slave Address */
81#define VT1632_TMDS_I2C_ADDR 0x10
82
83/**************************************************/
84/* Definition LVDS Trasmitter Information */
85/**************************************************/
86
87/* Definition LVDS Trasmitter Index */
88#define NON_LVDS_TRANSMITTER 0x00
89#define VT1631_LVDS 0x01
90#define VT1636_LVDS 0x0E
91#define INTEGRATED_LVDS 0x41
92
93/* Definition Digital Transmitter Mode */
94#define TX_DATA_12_BITS 0x01
95#define TX_DATA_24_BITS 0x02
96#define TX_DATA_DDR_MODE 0x04
97#define TX_DATA_SDR_MODE 0x08
98
99/* Definition LVDS Trasmitter I2C Slave Address */
100#define VT1631_LVDS_I2C_ADDR 0x70
101#define VT3271_LVDS_I2C_ADDR 0x80
102#define VT1636_LVDS_I2C_ADDR 0x80
103
104struct tmds_chip_information {
105 int tmds_chip_name;
106 int tmds_chip_slave_addr;
107 int dvi_panel_id;
108 int data_mode;
109 int output_interface;
110 int i2c_port;
111 int device_type;
112};
113
114struct lvds_chip_information {
115 int lvds_chip_name;
116 int lvds_chip_slave_addr;
117 int data_mode;
118 int output_interface;
119 int i2c_port;
120};
121
122struct chip_information {
123 int gfx_chip_name;
124 int gfx_chip_revision;
125 int chip_on_slot;
126 struct tmds_chip_information tmds_chip_info;
127 struct lvds_chip_information lvds_chip_info;
128 struct lvds_chip_information lvds_chip_info2;
129};
130
131struct crt_setting_information {
132 int iga_path;
133 int h_active;
134 int v_active;
135 int bpp;
136 int refresh_rate;
137};
138
139struct tmds_setting_information {
140 int iga_path;
141 int h_active;
142 int v_active;
143 int bpp;
144 int refresh_rate;
145 int get_dvi_size_method;
146 int max_pixel_clock;
147 int dvi_panel_size;
148 int dvi_panel_hres;
149 int dvi_panel_vres;
150 int native_size;
151};
152
153struct lvds_setting_information {
154 int iga_path;
155 int h_active;
156 int v_active;
157 int bpp;
158 int refresh_rate;
159 int get_lcd_size_method;
160 int lcd_panel_id;
161 int lcd_panel_size;
162 int lcd_panel_hres;
163 int lcd_panel_vres;
164 int display_method;
165 int device_lcd_dualedge;
166 int LCDDithering;
167 int lcd_mode;
168 u32 vclk; /*panel mode clock value */
169};
170
171struct GFX_DPA_SETTING {
172 int ClkRangeIndex;
173 u8 DVP0; /* CR96[3:0] */
174 u8 DVP0DataDri_S1; /* SR2A[5] */
175 u8 DVP0DataDri_S; /* SR1B[1] */
176 u8 DVP0ClockDri_S1; /* SR2A[4] */
177 u8 DVP0ClockDri_S; /* SR1E[2] */
178 u8 DVP1; /* CR9B[3:0] */
179 u8 DVP1Driving; /* SR65[3:0], Data and Clock driving */
180 u8 DFPHigh; /* CR97[3:0] */
181 u8 DFPLow; /* CR99[3:0] */
182
183};
184
185struct VT1636_DPA_SETTING {
186 int PanelSizeID;
187 u8 CLK_SEL_ST1;
188 u8 CLK_SEL_ST2;
189};
190#endif /* __CHIP_H__ */
diff --git a/drivers/video/via/debug.h b/drivers/video/via/debug.h
new file mode 100644
index 000000000000..86eacc2017f3
--- /dev/null
+++ b/drivers/video/via/debug.h
@@ -0,0 +1,41 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
14 * for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21#ifndef __DEBUG_H__
22#define __DEBUG_H__
23
24#ifndef VIAFB_DEBUG
25#define VIAFB_DEBUG 0
26#endif
27
28#if VIAFB_DEBUG
29#define DEBUG_MSG(f, a...) printk(f, ## a)
30#else
31#define DEBUG_MSG(f, a...)
32#endif
33
34#define VIAFB_WARN 0
35#if VIAFB_WARN
36#define WARN_MSG(f, a...) printk(f, ## a)
37#else
38#define WARN_MSG(f, a...)
39#endif
40
41#endif /* __DEBUG_H__ */
diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c
new file mode 100644
index 000000000000..d6965447ca69
--- /dev/null
+++ b/drivers/video/via/dvi.c
@@ -0,0 +1,682 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
14 * for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21#include "global.h"
22
23static void tmds_register_write(int index, u8 data);
24static int tmds_register_read(int index);
25static int tmds_register_read_bytes(int index, u8 *buff, int buff_len);
26static int check_reduce_blanking_mode(int mode_index,
27 int refresh_rate);
28static int dvi_get_panel_size_from_DDCv1(void);
29static int dvi_get_panel_size_from_DDCv2(void);
30static unsigned char dvi_get_panel_info(void);
31static int viafb_dvi_query_EDID(void);
32
33static int check_tmds_chip(int device_id_subaddr, int device_id)
34{
35 if (tmds_register_read(device_id_subaddr) == device_id)
36 return OK;
37 else
38 return FAIL;
39}
40
41void viafb_init_dvi_size(void)
42{
43 DEBUG_MSG(KERN_INFO "viafb_init_dvi_size()\n");
44 DEBUG_MSG(KERN_INFO
45 "viaparinfo->tmds_setting_info->get_dvi_size_method %d\n",
46 viaparinfo->tmds_setting_info->get_dvi_size_method);
47
48 switch (viaparinfo->tmds_setting_info->get_dvi_size_method) {
49 case GET_DVI_SIZE_BY_SYSTEM_BIOS:
50 break;
51 case GET_DVI_SZIE_BY_HW_STRAPPING:
52 break;
53 case GET_DVI_SIZE_BY_VGA_BIOS:
54 default:
55 dvi_get_panel_info();
56 break;
57 }
58 return;
59}
60
61int viafb_tmds_trasmitter_identify(void)
62{
63 unsigned char sr2a = 0, sr1e = 0, sr3e = 0;
64
65 /* Turn on ouputting pad */
66 switch (viaparinfo->chip_info->gfx_chip_name) {
67 case UNICHROME_K8M890:
68 /*=* DFP Low Pad on *=*/
69 sr2a = viafb_read_reg(VIASR, SR2A);
70 viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1);
71 break;
72
73 case UNICHROME_P4M900:
74 case UNICHROME_P4M890:
75 /* DFP Low Pad on */
76 sr2a = viafb_read_reg(VIASR, SR2A);
77 viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1);
78 /* DVP0 Pad on */
79 sr1e = viafb_read_reg(VIASR, SR1E);
80 viafb_write_reg_mask(SR1E, VIASR, 0xC0, BIT6 + BIT7);
81 break;
82
83 default:
84 /* DVP0/DVP1 Pad on */
85 sr1e = viafb_read_reg(VIASR, SR1E);
86 viafb_write_reg_mask(SR1E, VIASR, 0xF0, BIT4 +
87 BIT5 + BIT6 + BIT7);
88 /* SR3E[1]Multi-function selection:
89 0 = Emulate I2C and DDC bus by GPIO2/3/4. */
90 sr3e = viafb_read_reg(VIASR, SR3E);
91 viafb_write_reg_mask(SR3E, VIASR, 0x0, BIT5);
92 break;
93 }
94
95 /* Check for VT1632: */
96 viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = VT1632_TMDS;
97 viaparinfo->chip_info->
98 tmds_chip_info.tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR;
99 viaparinfo->chip_info->tmds_chip_info.i2c_port = I2CPORTINDEX;
100 if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) != FAIL) {
101 /*
102 * Currently only support 12bits,dual edge,add 24bits mode later
103 */
104 tmds_register_write(0x08, 0x3b);
105
106 DEBUG_MSG(KERN_INFO "\n VT1632 TMDS ! \n");
107 DEBUG_MSG(KERN_INFO "\n %2d",
108 viaparinfo->chip_info->tmds_chip_info.tmds_chip_name);
109 DEBUG_MSG(KERN_INFO "\n %2d",
110 viaparinfo->chip_info->tmds_chip_info.i2c_port);
111 return OK;
112 } else {
113 viaparinfo->chip_info->tmds_chip_info.i2c_port = GPIOPORTINDEX;
114 if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID)
115 != FAIL) {
116 tmds_register_write(0x08, 0x3b);
117 DEBUG_MSG(KERN_INFO "\n VT1632 TMDS ! \n");
118 DEBUG_MSG(KERN_INFO "\n %2d",
119 viaparinfo->chip_info->
120 tmds_chip_info.tmds_chip_name);
121 DEBUG_MSG(KERN_INFO "\n %2d",
122 viaparinfo->chip_info->
123 tmds_chip_info.i2c_port);
124 return OK;
125 }
126 }
127
128 viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = INTEGRATED_TMDS;
129
130 if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) &&
131 ((viafb_display_hardware_layout == HW_LAYOUT_DVI_ONLY) ||
132 (viafb_display_hardware_layout == HW_LAYOUT_LCD_DVI))) {
133 DEBUG_MSG(KERN_INFO "\n Integrated TMDS ! \n");
134 return OK;
135 }
136
137 switch (viaparinfo->chip_info->gfx_chip_name) {
138 case UNICHROME_K8M890:
139 viafb_write_reg(SR2A, VIASR, sr2a);
140 break;
141
142 case UNICHROME_P4M900:
143 case UNICHROME_P4M890:
144 viafb_write_reg(SR2A, VIASR, sr2a);
145 viafb_write_reg(SR1E, VIASR, sr1e);
146 break;
147
148 default:
149 viafb_write_reg(SR1E, VIASR, sr1e);
150 viafb_write_reg(SR3E, VIASR, sr3e);
151 break;
152 }
153
154 viaparinfo->chip_info->
155 tmds_chip_info.tmds_chip_name = NON_TMDS_TRANSMITTER;
156 viaparinfo->chip_info->tmds_chip_info.
157 tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR;
158 return FAIL;
159}
160
161static void tmds_register_write(int index, u8 data)
162{
163 viaparinfo->i2c_stuff.i2c_port =
164 viaparinfo->chip_info->tmds_chip_info.i2c_port;
165
166 viafb_i2c_writebyte(viaparinfo->chip_info->tmds_chip_info.
167 tmds_chip_slave_addr, index,
168 data);
169}
170
171static int tmds_register_read(int index)
172{
173 u8 data;
174
175 viaparinfo->i2c_stuff.i2c_port =
176 viaparinfo->chip_info->tmds_chip_info.i2c_port;
177 viafb_i2c_readbyte((u8) viaparinfo->chip_info->
178 tmds_chip_info.tmds_chip_slave_addr,
179 (u8) index, &data);
180 return data;
181}
182
183static int tmds_register_read_bytes(int index, u8 *buff, int buff_len)
184{
185 viaparinfo->i2c_stuff.i2c_port =
186 viaparinfo->chip_info->tmds_chip_info.i2c_port;
187 viafb_i2c_readbytes((u8) viaparinfo->chip_info->tmds_chip_info.
188 tmds_chip_slave_addr, (u8) index, buff, buff_len);
189 return 0;
190}
191
192static int check_reduce_blanking_mode(int mode_index,
193 int refresh_rate)
194{
195 if (refresh_rate != 60)
196 return false;
197
198 switch (mode_index) {
199 /* Following modes have reduce blanking mode. */
200 case VIA_RES_1360X768:
201 case VIA_RES_1400X1050:
202 case VIA_RES_1440X900:
203 case VIA_RES_1600X900:
204 case VIA_RES_1680X1050:
205 case VIA_RES_1920X1080:
206 case VIA_RES_1920X1200:
207 break;
208
209 default:
210 DEBUG_MSG(KERN_INFO
211 "This dvi mode %d have no reduce blanking mode!\n",
212 mode_index);
213 return false;
214 }
215
216 return true;
217}
218
219/* DVI Set Mode */
220void viafb_dvi_set_mode(int video_index, int mode_bpp, int set_iga)
221{
222 struct VideoModeTable *videoMode = NULL;
223 struct crt_mode_table *pDviTiming;
224 unsigned long desirePixelClock, maxPixelClock;
225 int status = 0;
226 videoMode = viafb_get_modetbl_pointer(video_index);
227 pDviTiming = videoMode->crtc;
228 desirePixelClock = pDviTiming->clk / 1000000;
229 maxPixelClock = (unsigned long)viaparinfo->
230 tmds_setting_info->max_pixel_clock;
231
232 DEBUG_MSG(KERN_INFO "\nDVI_set_mode!!\n");
233
234 if ((maxPixelClock != 0) && (desirePixelClock > maxPixelClock)) {
235 /*Check if reduce-blanking mode is exist */
236 status =
237 check_reduce_blanking_mode(video_index,
238 pDviTiming->refresh_rate);
239 if (status) {
240 video_index += 100; /*Use reduce-blanking mode */
241 videoMode = viafb_get_modetbl_pointer(video_index);
242 pDviTiming = videoMode->crtc;
243 DEBUG_MSG(KERN_INFO
244 "DVI use reduce blanking mode %d!!\n",
245 video_index);
246 }
247 }
248 viafb_fill_crtc_timing(pDviTiming, video_index, mode_bpp / 8, set_iga);
249 viafb_set_output_path(DEVICE_DVI, set_iga,
250 viaparinfo->chip_info->tmds_chip_info.output_interface);
251}
252
253/* Sense DVI Connector */
254int viafb_dvi_sense(void)
255{
256 u8 RegSR1E = 0, RegSR3E = 0, RegCR6B = 0, RegCR91 = 0,
257 RegCR93 = 0, RegCR9B = 0, data;
258 int ret = false;
259
260 DEBUG_MSG(KERN_INFO "viafb_dvi_sense!!\n");
261
262 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
263 /* DI1 Pad on */
264 RegSR1E = viafb_read_reg(VIASR, SR1E);
265 viafb_write_reg(SR1E, VIASR, RegSR1E | 0x30);
266
267 /* CR6B[0]VCK Input Selection: 1 = External clock. */
268 RegCR6B = viafb_read_reg(VIACR, CR6B);
269 viafb_write_reg(CR6B, VIACR, RegCR6B | 0x08);
270
271 /* CR91[4] VDD On [3] Data On [2] VEE On [1] Back Light Off
272 [0] Software Control Power Sequence */
273 RegCR91 = viafb_read_reg(VIACR, CR91);
274 viafb_write_reg(CR91, VIACR, 0x1D);
275
276 /* CR93[7] DI1 Data Source Selection: 1 = DSP2.
277 CR93[5] DI1 Clock Source: 1 = internal.
278 CR93[4] DI1 Clock Polarity.
279 CR93[3:1] DI1 Clock Adjust. CR93[0] DI1 enable */
280 RegCR93 = viafb_read_reg(VIACR, CR93);
281 viafb_write_reg(CR93, VIACR, 0x01);
282 } else {
283 /* DVP0/DVP1 Pad on */
284 RegSR1E = viafb_read_reg(VIASR, SR1E);
285 viafb_write_reg(SR1E, VIASR, RegSR1E | 0xF0);
286
287 /* SR3E[1]Multi-function selection:
288 0 = Emulate I2C and DDC bus by GPIO2/3/4. */
289 RegSR3E = viafb_read_reg(VIASR, SR3E);
290 viafb_write_reg(SR3E, VIASR, RegSR3E & (~0x20));
291
292 /* CR91[4] VDD On [3] Data On [2] VEE On [1] Back Light Off
293 [0] Software Control Power Sequence */
294 RegCR91 = viafb_read_reg(VIACR, CR91);
295 viafb_write_reg(CR91, VIACR, 0x1D);
296
297 /*CR9B[4] DVP1 Data Source Selection: 1 = From secondary
298 display.CR9B[2:0] DVP1 Clock Adjust */
299 RegCR9B = viafb_read_reg(VIACR, CR9B);
300 viafb_write_reg(CR9B, VIACR, 0x01);
301 }
302
303 data = (u8) tmds_register_read(0x09);
304 if (data & 0x04)
305 ret = true;
306
307 if (ret == false) {
308 if (viafb_dvi_query_EDID())
309 ret = true;
310 }
311
312 /* Restore status */
313 viafb_write_reg(SR1E, VIASR, RegSR1E);
314 viafb_write_reg(CR91, VIACR, RegCR91);
315 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
316 viafb_write_reg(CR6B, VIACR, RegCR6B);
317 viafb_write_reg(CR93, VIACR, RegCR93);
318 } else {
319 viafb_write_reg(SR3E, VIASR, RegSR3E);
320 viafb_write_reg(CR9B, VIACR, RegCR9B);
321 }
322
323 return ret;
324}
325
326/* Query Flat Panel's EDID Table Version Through DVI Connector */
327static int viafb_dvi_query_EDID(void)
328{
329 u8 data0, data1;
330 int restore;
331
332 DEBUG_MSG(KERN_INFO "viafb_dvi_query_EDID!!\n");
333
334 restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
335 viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA0;
336
337 data0 = (u8) tmds_register_read(0x00);
338 data1 = (u8) tmds_register_read(0x01);
339 if ((data0 == 0) && (data1 == 0xFF)) {
340 viaparinfo->chip_info->
341 tmds_chip_info.tmds_chip_slave_addr = restore;
342 return EDID_VERSION_1; /* Found EDID1 Table */
343 }
344
345 data0 = (u8) tmds_register_read(0x00);
346 viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
347 if (data0 == 0x20)
348 return EDID_VERSION_2; /* Found EDID2 Table */
349 else
350 return false;
351}
352
353/*
354 *
355 * int dvi_get_panel_size_from_DDCv1(void)
356 *
357 * - Get Panel Size Using EDID1 Table
358 *
359 * Return Type: int
360 *
361 */
362static int dvi_get_panel_size_from_DDCv1(void)
363{
364 int i, max_h = 0, max_v = 0, tmp, restore;
365 unsigned char rData;
366 unsigned char EDID_DATA[18];
367
368 DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv1 \n");
369
370 restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
371 viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA0;
372
373 rData = tmds_register_read(0x23);
374 if (rData & 0x3C)
375 max_h = 640;
376 if (rData & 0xC0)
377 max_h = 720;
378 if (rData & 0x03)
379 max_h = 800;
380
381 rData = tmds_register_read(0x24);
382 if (rData & 0xC0)
383 max_h = 800;
384 if (rData & 0x1E)
385 max_h = 1024;
386 if (rData & 0x01)
387 max_h = 1280;
388
389 for (i = 0x25; i < 0x6D; i++) {
390 switch (i) {
391 case 0x26:
392 case 0x28:
393 case 0x2A:
394 case 0x2C:
395 case 0x2E:
396 case 0x30:
397 case 0x32:
398 case 0x34:
399 rData = tmds_register_read(i);
400 if (rData == 1)
401 break;
402 /* data = (data + 31) * 8 */
403 tmp = (rData + 31) << 3;
404 if (tmp > max_h)
405 max_h = tmp;
406 break;
407
408 case 0x36:
409 case 0x48:
410 case 0x5A:
411 case 0x6C:
412 tmds_register_read_bytes(i, EDID_DATA, 10);
413 if (!(EDID_DATA[0] || EDID_DATA[1])) {
414 /* The first two byte must be zero. */
415 if (EDID_DATA[3] == 0xFD) {
416 /* To get max pixel clock. */
417 viaparinfo->tmds_setting_info->
418 max_pixel_clock = EDID_DATA[9] * 10;
419 }
420 }
421 break;
422
423 default:
424 break;
425 }
426 }
427
428 switch (max_h) {
429 case 640:
430 viaparinfo->tmds_setting_info->dvi_panel_size =
431 VIA_RES_640X480;
432 break;
433 case 800:
434 viaparinfo->tmds_setting_info->dvi_panel_size =
435 VIA_RES_800X600;
436 break;
437 case 1024:
438 viaparinfo->tmds_setting_info->dvi_panel_size =
439 VIA_RES_1024X768;
440 break;
441 case 1280:
442 viaparinfo->tmds_setting_info->dvi_panel_size =
443 VIA_RES_1280X1024;
444 break;
445 case 1400:
446 viaparinfo->tmds_setting_info->dvi_panel_size =
447 VIA_RES_1400X1050;
448 break;
449 case 1440:
450 viaparinfo->tmds_setting_info->dvi_panel_size =
451 VIA_RES_1440X1050;
452 break;
453 case 1600:
454 viaparinfo->tmds_setting_info->dvi_panel_size =
455 VIA_RES_1600X1200;
456 break;
457 case 1920:
458 if (max_v == 1200) {
459 viaparinfo->tmds_setting_info->dvi_panel_size =
460 VIA_RES_1920X1200;
461 } else {
462 viaparinfo->tmds_setting_info->dvi_panel_size =
463 VIA_RES_1920X1080;
464 }
465
466 break;
467 default:
468 viaparinfo->tmds_setting_info->dvi_panel_size =
469 VIA_RES_1024X768;
470 DEBUG_MSG(KERN_INFO "Unknow panel size max resolution = %d !\
471 set default panel size.\n", max_h);
472 break;
473 }
474
475 DEBUG_MSG(KERN_INFO "DVI max pixelclock = %d\n",
476 viaparinfo->tmds_setting_info->max_pixel_clock);
477 viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
478 return viaparinfo->tmds_setting_info->dvi_panel_size;
479}
480
481/*
482 *
483 * int dvi_get_panel_size_from_DDCv2(void)
484 *
485 * - Get Panel Size Using EDID2 Table
486 *
487 * Return Type: int
488 *
489 */
490static int dvi_get_panel_size_from_DDCv2(void)
491{
492 int HSize = 0, restore;
493 unsigned char R_Buffer[2];
494
495 DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv2 \n");
496
497 restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
498 viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA2;
499
500 /* Horizontal: 0x76, 0x77 */
501 tmds_register_read_bytes(0x76, R_Buffer, 2);
502 HSize = R_Buffer[0];
503 HSize += R_Buffer[1] << 8;
504
505 switch (HSize) {
506 case 640:
507 viaparinfo->tmds_setting_info->dvi_panel_size =
508 VIA_RES_640X480;
509 break;
510 case 800:
511 viaparinfo->tmds_setting_info->dvi_panel_size =
512 VIA_RES_800X600;
513 break;
514 case 1024:
515 viaparinfo->tmds_setting_info->dvi_panel_size =
516 VIA_RES_1024X768;
517 break;
518 case 1280:
519 viaparinfo->tmds_setting_info->dvi_panel_size =
520 VIA_RES_1280X1024;
521 break;
522 case 1400:
523 viaparinfo->tmds_setting_info->dvi_panel_size =
524 VIA_RES_1400X1050;
525 break;
526 case 1440:
527 viaparinfo->tmds_setting_info->dvi_panel_size =
528 VIA_RES_1440X1050;
529 break;
530 case 1600:
531 viaparinfo->tmds_setting_info->dvi_panel_size =
532 VIA_RES_1600X1200;
533 break;
534 default:
535 viaparinfo->tmds_setting_info->dvi_panel_size =
536 VIA_RES_1024X768;
537 DEBUG_MSG(KERN_INFO "Unknow panel size max resolution = %d!\
538 set default panel size.\n", HSize);
539 break;
540 }
541
542 viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
543 return viaparinfo->tmds_setting_info->dvi_panel_size;
544}
545
546/*
547 *
548 * unsigned char dvi_get_panel_info(void)
549 *
550 * - Get Panel Size
551 *
552 * Return Type: unsigned char
553 */
554static unsigned char dvi_get_panel_info(void)
555{
556 unsigned char dvipanelsize;
557 DEBUG_MSG(KERN_INFO "dvi_get_panel_info! \n");
558
559 viafb_dvi_sense();
560 switch (viafb_dvi_query_EDID()) {
561 case 1:
562 dvi_get_panel_size_from_DDCv1();
563 break;
564 case 2:
565 dvi_get_panel_size_from_DDCv2();
566 break;
567 default:
568 break;
569 }
570
571 DEBUG_MSG(KERN_INFO "dvi panel size is %2d \n",
572 viaparinfo->tmds_setting_info->dvi_panel_size);
573 dvipanelsize = (unsigned char)(viaparinfo->
574 tmds_setting_info->dvi_panel_size);
575 return dvipanelsize;
576}
577
578/* If Disable DVI, turn off pad */
579void viafb_dvi_disable(void)
580{
581 if (viaparinfo->chip_info->
582 tmds_chip_info.output_interface == INTERFACE_DVP0)
583 viafb_write_reg(SR1E, VIASR,
584 viafb_read_reg(VIASR, SR1E) & (~0xC0));
585
586 if (viaparinfo->chip_info->
587 tmds_chip_info.output_interface == INTERFACE_DVP1)
588 viafb_write_reg(SR1E, VIASR,
589 viafb_read_reg(VIASR, SR1E) & (~0x30));
590
591 if (viaparinfo->chip_info->
592 tmds_chip_info.output_interface == INTERFACE_DFP_HIGH)
593 viafb_write_reg(SR2A, VIASR,
594 viafb_read_reg(VIASR, SR2A) & (~0x0C));
595
596 if (viaparinfo->chip_info->
597 tmds_chip_info.output_interface == INTERFACE_DFP_LOW)
598 viafb_write_reg(SR2A, VIASR,
599 viafb_read_reg(VIASR, SR2A) & (~0x03));
600
601 if (viaparinfo->chip_info->
602 tmds_chip_info.output_interface == INTERFACE_TMDS)
603 /* Turn off TMDS power. */
604 viafb_write_reg(CRD2, VIACR,
605 viafb_read_reg(VIACR, CRD2) | 0x08);
606}
607
608/* If Enable DVI, turn off pad */
609void viafb_dvi_enable(void)
610{
611 u8 data;
612
613 if (viaparinfo->chip_info->
614 tmds_chip_info.output_interface == INTERFACE_DVP0) {
615 viafb_write_reg(SR1E, VIASR,
616 viafb_read_reg(VIASR, SR1E) | 0xC0);
617 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
618 tmds_register_write(0x88, 0x3b);
619 else
620 /*clear CR91[5] to direct on display period
621 in the secondary diplay path */
622 viafb_write_reg(CR91, VIACR,
623 viafb_read_reg(VIACR, CR91) & 0xDF);
624 }
625
626 if (viaparinfo->chip_info->
627 tmds_chip_info.output_interface == INTERFACE_DVP1) {
628 viafb_write_reg(SR1E, VIASR,
629 viafb_read_reg(VIASR, SR1E) | 0x30);
630
631 /*fix dvi cann't be enabled with MB VT5718C4 - Al Zhang */
632 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
633 tmds_register_write(0x88, 0x3b);
634 } else {
635 /*clear CR91[5] to direct on display period
636 in the secondary diplay path */
637 viafb_write_reg(CR91, VIACR,
638 viafb_read_reg(VIACR, CR91) & 0xDF);
639 }
640
641 /*fix DVI cannot enable on EPIA-M board */
642 if (viafb_platform_epia_dvi == 1) {
643 viafb_write_reg_mask(CR91, VIACR, 0x1f, 0x1f);
644 viafb_write_reg_mask(CR88, VIACR, 0x00, BIT6 + BIT0);
645 if (viafb_bus_width == 24) {
646 if (viafb_device_lcd_dualedge == 1)
647 data = 0x3F;
648 else
649 data = 0x37;
650 viafb_i2c_writebyte(viaparinfo->chip_info->
651 tmds_chip_info.
652 tmds_chip_slave_addr,
653 0x08, data);
654 }
655 }
656 }
657
658 if (viaparinfo->chip_info->
659 tmds_chip_info.output_interface == INTERFACE_DFP_HIGH) {
660 viafb_write_reg(SR2A, VIASR,
661 viafb_read_reg(VIASR, SR2A) | 0x0C);
662 viafb_write_reg(CR91, VIACR,
663 viafb_read_reg(VIACR, CR91) & 0xDF);
664 }
665
666 if (viaparinfo->chip_info->
667 tmds_chip_info.output_interface == INTERFACE_DFP_LOW) {
668 viafb_write_reg(SR2A, VIASR,
669 viafb_read_reg(VIASR, SR2A) | 0x03);
670 viafb_write_reg(CR91, VIACR,
671 viafb_read_reg(VIACR, CR91) & 0xDF);
672 }
673 if (viaparinfo->chip_info->
674 tmds_chip_info.output_interface == INTERFACE_TMDS) {
675 /* Turn on Display period in the panel path. */
676 viafb_write_reg_mask(CR91, VIACR, 0, BIT7);
677
678 /* Turn on TMDS power. */
679 viafb_write_reg_mask(CRD2, VIACR, 0, BIT3);
680 }
681}
682
diff --git a/drivers/video/via/dvi.h b/drivers/video/via/dvi.h
new file mode 100644
index 000000000000..e1ec37fb0dc3
--- /dev/null
+++ b/drivers/video/via/dvi.h
@@ -0,0 +1,64 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
14 * for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22#ifndef __DVI_H__
23#define __DVI_H__
24
25/*Definition TMDS Device ID register*/
26#define VT1632_DEVICE_ID_REG 0x02
27#define VT1632_DEVICE_ID 0x92
28
29#define GET_DVI_SIZE_BY_SYSTEM_BIOS 0x01
30#define GET_DVI_SIZE_BY_VGA_BIOS 0x02
31#define GET_DVI_SZIE_BY_HW_STRAPPING 0x03
32
33/* Definition DVI Panel ID*/
34/* Resolution: 640x480, Channel: single, Dithering: Enable */
35#define DVI_PANEL_ID0_640X480 0x00
36/* Resolution: 800x600, Channel: single, Dithering: Enable */
37#define DVI_PANEL_ID1_800x600 0x01
38/* Resolution: 1024x768, Channel: single, Dithering: Enable */
39#define DVI_PANEL_ID1_1024x768 0x02
40/* Resolution: 1280x768, Channel: single, Dithering: Enable */
41#define DVI_PANEL_ID1_1280x768 0x03
42/* Resolution: 1280x1024, Channel: dual, Dithering: Enable */
43#define DVI_PANEL_ID1_1280x1024 0x04
44/* Resolution: 1400x1050, Channel: dual, Dithering: Enable */
45#define DVI_PANEL_ID1_1400x1050 0x05
46/* Resolution: 1600x1200, Channel: dual, Dithering: Enable */
47#define DVI_PANEL_ID1_1600x1200 0x06
48
49/* Define the version of EDID*/
50#define EDID_VERSION_1 1
51#define EDID_VERSION_2 2
52
53#define DEV_CONNECT_DVI 0x01
54#define DEV_CONNECT_HDMI 0x02
55
56struct VideoModeTable *viafb_get_cea_mode_tbl_pointer(int Index);
57int viafb_dvi_sense(void);
58void viafb_dvi_disable(void);
59void viafb_dvi_enable(void);
60int viafb_tmds_trasmitter_identify(void);
61void viafb_init_dvi_size(void);
62void viafb_dvi_set_mode(int video_index, int mode_bpp, int set_iga);
63
64#endif /* __DVI_H__ */
diff --git a/drivers/video/via/global.c b/drivers/video/via/global.c
new file mode 100644
index 000000000000..468be2425af3
--- /dev/null
+++ b/drivers/video/via/global.c
@@ -0,0 +1,60 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
14 * for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21#include "global.h"
22int viafb_platform_epia_dvi = STATE_OFF;
23int viafb_device_lcd_dualedge = STATE_OFF;
24int viafb_bus_width = 12;
25int viafb_display_hardware_layout = HW_LAYOUT_LCD_DVI;
26int viafb_memsize;
27int viafb_DeviceStatus = CRT_Device;
28int viafb_hotplug;
29int viafb_refresh = 60;
30int viafb_refresh1 = 60;
31int viafb_lcd_dsp_method = LCD_EXPANDSION;
32int viafb_lcd_mode = LCD_OPENLDI;
33int viafb_bpp = 32;
34int viafb_bpp1 = 32;
35int viafb_accel = 1;
36int viafb_CRT_ON = 1;
37int viafb_DVI_ON;
38int viafb_LCD_ON ;
39int viafb_LCD2_ON;
40int viafb_SAMM_ON;
41int viafb_dual_fb;
42int viafb_hotplug_Xres = 640;
43int viafb_hotplug_Yres = 480;
44int viafb_hotplug_bpp = 32;
45int viafb_hotplug_refresh = 60;
46unsigned int viafb_second_offset;
47int viafb_second_size;
48int viafb_primary_dev = None_Device;
49void __iomem *viafb_FB_MM;
50unsigned int viafb_second_xres = 640;
51unsigned int viafb_second_yres = 480;
52unsigned int viafb_second_virtual_xres;
53unsigned int viafb_second_virtual_yres;
54int viafb_lcd_panel_id = LCD_PANEL_ID_MAXIMUM + 1;
55struct fb_cursor viacursor;
56struct fb_info *viafbinfo;
57struct fb_info *viafbinfo1;
58struct viafb_par *viaparinfo;
59struct viafb_par *viaparinfo1;
60
diff --git a/drivers/video/via/global.h b/drivers/video/via/global.h
new file mode 100644
index 000000000000..8e5263c5b812
--- /dev/null
+++ b/drivers/video/via/global.h
@@ -0,0 +1,90 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
14 * for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22#ifndef __GLOBAL_H__
23#define __GLOBAL_H__
24
25#include <linux/fb.h>
26#include <linux/delay.h>
27#include <linux/ioport.h>
28#include <linux/pci.h>
29#include <linux/io.h>
30#include <linux/uaccess.h>
31#include <linux/init.h>
32#include <linux/proc_fs.h>
33#include <linux/console.h>
34#include <linux/timer.h>
35
36#include "debug.h"
37
38#include "iface.h"
39#include "viafbdev.h"
40#include "chip.h"
41#include "debug.h"
42#include "accel.h"
43#include "share.h"
44#include "dvi.h"
45#include "viamode.h"
46#include "via_i2c.h"
47#include "hw.h"
48
49#include "lcd.h"
50#include "ioctl.h"
51#include "viamode.h"
52#include "via_utility.h"
53#include "vt1636.h"
54#include "tblDPASetting.h"
55#include "tbl1636.h"
56#include "viafbdev.h"
57
58/* External struct*/
59
60extern int viafb_platform_epia_dvi;
61extern int viafb_device_lcd_dualedge;
62extern int viafb_bus_width;
63extern int viafb_display_hardware_layout;
64extern struct offset offset_reg;
65extern struct viafb_par *viaparinfo;
66extern struct viafb_par *viaparinfo1;
67extern struct fb_info *viafbinfo;
68extern struct fb_info *viafbinfo1;
69extern int viafb_DeviceStatus;
70extern int viafb_refresh;
71extern int viafb_refresh1;
72extern int viafb_lcd_dsp_method;
73extern int viafb_lcd_mode;
74extern int viafb_bpp;
75extern int viafb_bpp1;
76
77extern int viafb_CRT_ON;
78extern int viafb_hotplug_Xres;
79extern int viafb_hotplug_Yres;
80extern int viafb_hotplug_bpp;
81extern int viafb_hotplug_refresh;
82extern int viafb_primary_dev;
83extern void __iomem *viafb_FB_MM;
84extern struct fb_cursor viacursor;
85
86extern unsigned int viafb_second_xres;
87extern unsigned int viafb_second_yres;
88extern int viafb_lcd_panel_id;
89
90#endif /* __GLOBAL_H__ */
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c
new file mode 100644
index 000000000000..fcd53ceb88fa
--- /dev/null
+++ b/drivers/video/via/hw.c
@@ -0,0 +1,2865 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
14 * for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22#include "global.h"
23
24static const struct pci_device_id_info pciidlist[] = {
25 {PCI_VIA_VENDOR_ID, UNICHROME_CLE266_DID, UNICHROME_CLE266},
26 {PCI_VIA_VENDOR_ID, UNICHROME_PM800_DID, UNICHROME_PM800},
27 {PCI_VIA_VENDOR_ID, UNICHROME_K400_DID, UNICHROME_K400},
28 {PCI_VIA_VENDOR_ID, UNICHROME_K800_DID, UNICHROME_K800},
29 {PCI_VIA_VENDOR_ID, UNICHROME_CN700_DID, UNICHROME_CN700},
30 {PCI_VIA_VENDOR_ID, UNICHROME_P4M890_DID, UNICHROME_P4M890},
31 {PCI_VIA_VENDOR_ID, UNICHROME_K8M890_DID, UNICHROME_K8M890},
32 {PCI_VIA_VENDOR_ID, UNICHROME_CX700_DID, UNICHROME_CX700},
33 {PCI_VIA_VENDOR_ID, UNICHROME_P4M900_DID, UNICHROME_P4M900},
34 {PCI_VIA_VENDOR_ID, UNICHROME_CN750_DID, UNICHROME_CN750},
35 {PCI_VIA_VENDOR_ID, UNICHROME_VX800_DID, UNICHROME_VX800},
36 {0, 0, 0}
37};
38
39struct offset offset_reg = {
40 /* IGA1 Offset Register */
41 {IGA1_OFFSET_REG_NUM, {{CR13, 0, 7}, {CR35, 5, 7} } },
42 /* IGA2 Offset Register */
43 {IGA2_OFFSET_REG_NUM, {{CR66, 0, 7}, {CR67, 0, 1} } }
44};
45
46static struct pll_map pll_value[] = {
47 {CLK_25_175M, CLE266_PLL_25_175M, K800_PLL_25_175M, CX700_25_175M},
48 {CLK_29_581M, CLE266_PLL_29_581M, K800_PLL_29_581M, CX700_29_581M},
49 {CLK_26_880M, CLE266_PLL_26_880M, K800_PLL_26_880M, CX700_26_880M},
50 {CLK_31_490M, CLE266_PLL_31_490M, K800_PLL_31_490M, CX700_31_490M},
51 {CLK_31_500M, CLE266_PLL_31_500M, K800_PLL_31_500M, CX700_31_500M},
52 {CLK_31_728M, CLE266_PLL_31_728M, K800_PLL_31_728M, CX700_31_728M},
53 {CLK_32_668M, CLE266_PLL_32_668M, K800_PLL_32_668M, CX700_32_668M},
54 {CLK_36_000M, CLE266_PLL_36_000M, K800_PLL_36_000M, CX700_36_000M},
55 {CLK_40_000M, CLE266_PLL_40_000M, K800_PLL_40_000M, CX700_40_000M},
56 {CLK_41_291M, CLE266_PLL_41_291M, K800_PLL_41_291M, CX700_41_291M},
57 {CLK_43_163M, CLE266_PLL_43_163M, K800_PLL_43_163M, CX700_43_163M},
58 {CLK_45_250M, CLE266_PLL_45_250M, K800_PLL_45_250M, CX700_45_250M},
59 {CLK_46_000M, CLE266_PLL_46_000M, K800_PLL_46_000M, CX700_46_000M},
60 {CLK_46_996M, CLE266_PLL_46_996M, K800_PLL_46_996M, CX700_46_996M},
61 {CLK_48_000M, CLE266_PLL_48_000M, K800_PLL_48_000M, CX700_48_000M},
62 {CLK_48_875M, CLE266_PLL_48_875M, K800_PLL_48_875M, CX700_48_875M},
63 {CLK_49_500M, CLE266_PLL_49_500M, K800_PLL_49_500M, CX700_49_500M},
64 {CLK_52_406M, CLE266_PLL_52_406M, K800_PLL_52_406M, CX700_52_406M},
65 {CLK_52_977M, CLE266_PLL_52_977M, K800_PLL_52_977M, CX700_52_977M},
66 {CLK_56_250M, CLE266_PLL_56_250M, K800_PLL_56_250M, CX700_56_250M},
67 {CLK_60_466M, CLE266_PLL_60_466M, K800_PLL_60_466M, CX700_60_466M},
68 {CLK_61_500M, CLE266_PLL_61_500M, K800_PLL_61_500M, CX700_61_500M},
69 {CLK_65_000M, CLE266_PLL_65_000M, K800_PLL_65_000M, CX700_65_000M},
70 {CLK_65_178M, CLE266_PLL_65_178M, K800_PLL_65_178M, CX700_65_178M},
71 {CLK_66_750M, CLE266_PLL_66_750M, K800_PLL_66_750M, CX700_66_750M},
72 {CLK_68_179M, CLE266_PLL_68_179M, K800_PLL_68_179M, CX700_68_179M},
73 {CLK_69_924M, CLE266_PLL_69_924M, K800_PLL_69_924M, CX700_69_924M},
74 {CLK_70_159M, CLE266_PLL_70_159M, K800_PLL_70_159M, CX700_70_159M},
75 {CLK_72_000M, CLE266_PLL_72_000M, K800_PLL_72_000M, CX700_72_000M},
76 {CLK_78_750M, CLE266_PLL_78_750M, K800_PLL_78_750M, CX700_78_750M},
77 {CLK_80_136M, CLE266_PLL_80_136M, K800_PLL_80_136M, CX700_80_136M},
78 {CLK_83_375M, CLE266_PLL_83_375M, K800_PLL_83_375M, CX700_83_375M},
79 {CLK_83_950M, CLE266_PLL_83_950M, K800_PLL_83_950M, CX700_83_950M},
80 {CLK_84_750M, CLE266_PLL_84_750M, K800_PLL_84_750M, CX700_84_750M},
81 {CLK_85_860M, CLE266_PLL_85_860M, K800_PLL_85_860M, CX700_85_860M},
82 {CLK_88_750M, CLE266_PLL_88_750M, K800_PLL_88_750M, CX700_88_750M},
83 {CLK_94_500M, CLE266_PLL_94_500M, K800_PLL_94_500M, CX700_94_500M},
84 {CLK_97_750M, CLE266_PLL_97_750M, K800_PLL_97_750M, CX700_97_750M},
85 {CLK_101_000M, CLE266_PLL_101_000M, K800_PLL_101_000M,
86 CX700_101_000M},
87 {CLK_106_500M, CLE266_PLL_106_500M, K800_PLL_106_500M,
88 CX700_106_500M},
89 {CLK_108_000M, CLE266_PLL_108_000M, K800_PLL_108_000M,
90 CX700_108_000M},
91 {CLK_113_309M, CLE266_PLL_113_309M, K800_PLL_113_309M,
92 CX700_113_309M},
93 {CLK_118_840M, CLE266_PLL_118_840M, K800_PLL_118_840M,
94 CX700_118_840M},
95 {CLK_119_000M, CLE266_PLL_119_000M, K800_PLL_119_000M,
96 CX700_119_000M},
97 {CLK_121_750M, CLE266_PLL_121_750M, K800_PLL_121_750M,
98 CX700_121_750M},
99 {CLK_125_104M, CLE266_PLL_125_104M, K800_PLL_125_104M,
100 CX700_125_104M},
101 {CLK_133_308M, CLE266_PLL_133_308M, K800_PLL_133_308M,
102 CX700_133_308M},
103 {CLK_135_000M, CLE266_PLL_135_000M, K800_PLL_135_000M,
104 CX700_135_000M},
105 {CLK_136_700M, CLE266_PLL_136_700M, K800_PLL_136_700M,
106 CX700_136_700M},
107 {CLK_138_400M, CLE266_PLL_138_400M, K800_PLL_138_400M,
108 CX700_138_400M},
109 {CLK_146_760M, CLE266_PLL_146_760M, K800_PLL_146_760M,
110 CX700_146_760M},
111 {CLK_153_920M, CLE266_PLL_153_920M, K800_PLL_153_920M,
112 CX700_153_920M},
113 {CLK_156_000M, CLE266_PLL_156_000M, K800_PLL_156_000M,
114 CX700_156_000M},
115 {CLK_157_500M, CLE266_PLL_157_500M, K800_PLL_157_500M,
116 CX700_157_500M},
117 {CLK_162_000M, CLE266_PLL_162_000M, K800_PLL_162_000M,
118 CX700_162_000M},
119 {CLK_187_000M, CLE266_PLL_187_000M, K800_PLL_187_000M,
120 CX700_187_000M},
121 {CLK_193_295M, CLE266_PLL_193_295M, K800_PLL_193_295M,
122 CX700_193_295M},
123 {CLK_202_500M, CLE266_PLL_202_500M, K800_PLL_202_500M,
124 CX700_202_500M},
125 {CLK_204_000M, CLE266_PLL_204_000M, K800_PLL_204_000M,
126 CX700_204_000M},
127 {CLK_218_500M, CLE266_PLL_218_500M, K800_PLL_218_500M,
128 CX700_218_500M},
129 {CLK_234_000M, CLE266_PLL_234_000M, K800_PLL_234_000M,
130 CX700_234_000M},
131 {CLK_267_250M, CLE266_PLL_267_250M, K800_PLL_267_250M,
132 CX700_267_250M},
133 {CLK_297_500M, CLE266_PLL_297_500M, K800_PLL_297_500M,
134 CX700_297_500M},
135 {CLK_74_481M, CLE266_PLL_74_481M, K800_PLL_74_481M, CX700_74_481M},
136 {CLK_172_798M, CLE266_PLL_172_798M, K800_PLL_172_798M,
137 CX700_172_798M},
138 {CLK_122_614M, CLE266_PLL_122_614M, K800_PLL_122_614M,
139 CX700_122_614M},
140 {CLK_74_270M, CLE266_PLL_74_270M, K800_PLL_74_270M, CX700_74_270M},
141 {CLK_148_500M, CLE266_PLL_148_500M, K800_PLL_148_500M,
142 CX700_148_500M}
143};
144
145static struct fifo_depth_select display_fifo_depth_reg = {
146 /* IGA1 FIFO Depth_Select */
147 {IGA1_FIFO_DEPTH_SELECT_REG_NUM, {{SR17, 0, 7} } },
148 /* IGA2 FIFO Depth_Select */
149 {IGA2_FIFO_DEPTH_SELECT_REG_NUM,
150 {{CR68, 4, 7}, {CR94, 7, 7}, {CR95, 7, 7} } }
151};
152
153static struct fifo_threshold_select fifo_threshold_select_reg = {
154 /* IGA1 FIFO Threshold Select */
155 {IGA1_FIFO_THRESHOLD_REG_NUM, {{SR16, 0, 5}, {SR16, 7, 7} } },
156 /* IGA2 FIFO Threshold Select */
157 {IGA2_FIFO_THRESHOLD_REG_NUM, {{CR68, 0, 3}, {CR95, 4, 6} } }
158};
159
160static struct fifo_high_threshold_select fifo_high_threshold_select_reg = {
161 /* IGA1 FIFO High Threshold Select */
162 {IGA1_FIFO_HIGH_THRESHOLD_REG_NUM, {{SR18, 0, 5}, {SR18, 7, 7} } },
163 /* IGA2 FIFO High Threshold Select */
164 {IGA2_FIFO_HIGH_THRESHOLD_REG_NUM, {{CR92, 0, 3}, {CR95, 0, 2} } }
165};
166
167static struct display_queue_expire_num display_queue_expire_num_reg = {
168 /* IGA1 Display Queue Expire Num */
169 {IGA1_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM, {{SR22, 0, 4} } },
170 /* IGA2 Display Queue Expire Num */
171 {IGA2_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM, {{CR94, 0, 6} } }
172};
173
174/* Definition Fetch Count Registers*/
175static struct fetch_count fetch_count_reg = {
176 /* IGA1 Fetch Count Register */
177 {IGA1_FETCH_COUNT_REG_NUM, {{SR1C, 0, 7}, {SR1D, 0, 1} } },
178 /* IGA2 Fetch Count Register */
179 {IGA2_FETCH_COUNT_REG_NUM, {{CR65, 0, 7}, {CR67, 2, 3} } }
180};
181
182static struct iga1_crtc_timing iga1_crtc_reg = {
183 /* IGA1 Horizontal Total */
184 {IGA1_HOR_TOTAL_REG_NUM, {{CR00, 0, 7}, {CR36, 3, 3} } },
185 /* IGA1 Horizontal Addressable Video */
186 {IGA1_HOR_ADDR_REG_NUM, {{CR01, 0, 7} } },
187 /* IGA1 Horizontal Blank Start */
188 {IGA1_HOR_BLANK_START_REG_NUM, {{CR02, 0, 7} } },
189 /* IGA1 Horizontal Blank End */
190 {IGA1_HOR_BLANK_END_REG_NUM,
191 {{CR03, 0, 4}, {CR05, 7, 7}, {CR33, 5, 5} } },
192 /* IGA1 Horizontal Sync Start */
193 {IGA1_HOR_SYNC_START_REG_NUM, {{CR04, 0, 7}, {CR33, 4, 4} } },
194 /* IGA1 Horizontal Sync End */
195 {IGA1_HOR_SYNC_END_REG_NUM, {{CR05, 0, 4} } },
196 /* IGA1 Vertical Total */
197 {IGA1_VER_TOTAL_REG_NUM,
198 {{CR06, 0, 7}, {CR07, 0, 0}, {CR07, 5, 5}, {CR35, 0, 0} } },
199 /* IGA1 Vertical Addressable Video */
200 {IGA1_VER_ADDR_REG_NUM,
201 {{CR12, 0, 7}, {CR07, 1, 1}, {CR07, 6, 6}, {CR35, 2, 2} } },
202 /* IGA1 Vertical Blank Start */
203 {IGA1_VER_BLANK_START_REG_NUM,
204 {{CR15, 0, 7}, {CR07, 3, 3}, {CR09, 5, 5}, {CR35, 3, 3} } },
205 /* IGA1 Vertical Blank End */
206 {IGA1_VER_BLANK_END_REG_NUM, {{CR16, 0, 7} } },
207 /* IGA1 Vertical Sync Start */
208 {IGA1_VER_SYNC_START_REG_NUM,
209 {{CR10, 0, 7}, {CR07, 2, 2}, {CR07, 7, 7}, {CR35, 1, 1} } },
210 /* IGA1 Vertical Sync End */
211 {IGA1_VER_SYNC_END_REG_NUM, {{CR11, 0, 3} } }
212};
213
214static struct iga2_crtc_timing iga2_crtc_reg = {
215 /* IGA2 Horizontal Total */
216 {IGA2_HOR_TOTAL_REG_NUM, {{CR50, 0, 7}, {CR55, 0, 3} } },
217 /* IGA2 Horizontal Addressable Video */
218 {IGA2_HOR_ADDR_REG_NUM, {{CR51, 0, 7}, {CR55, 4, 6} } },
219 /* IGA2 Horizontal Blank Start */
220 {IGA2_HOR_BLANK_START_REG_NUM, {{CR52, 0, 7}, {CR54, 0, 2} } },
221 /* IGA2 Horizontal Blank End */
222 {IGA2_HOR_BLANK_END_REG_NUM,
223 {{CR53, 0, 7}, {CR54, 3, 5}, {CR5D, 6, 6} } },
224 /* IGA2 Horizontal Sync Start */
225 {IGA2_HOR_SYNC_START_REG_NUM,
226 {{CR56, 0, 7}, {CR54, 6, 7}, {CR5C, 7, 7}, {CR5D, 7, 7} } },
227 /* IGA2 Horizontal Sync End */
228 {IGA2_HOR_SYNC_END_REG_NUM, {{CR57, 0, 7}, {CR5C, 6, 6} } },
229 /* IGA2 Vertical Total */
230 {IGA2_VER_TOTAL_REG_NUM, {{CR58, 0, 7}, {CR5D, 0, 2} } },
231 /* IGA2 Vertical Addressable Video */
232 {IGA2_VER_ADDR_REG_NUM, {{CR59, 0, 7}, {CR5D, 3, 5} } },
233 /* IGA2 Vertical Blank Start */
234 {IGA2_VER_BLANK_START_REG_NUM, {{CR5A, 0, 7}, {CR5C, 0, 2} } },
235 /* IGA2 Vertical Blank End */
236 {IGA2_VER_BLANK_END_REG_NUM, {{CR5B, 0, 7}, {CR5C, 3, 5} } },
237 /* IGA2 Vertical Sync Start */
238 {IGA2_VER_SYNC_START_REG_NUM, {{CR5E, 0, 7}, {CR5F, 5, 7} } },
239 /* IGA2 Vertical Sync End */
240 {IGA2_VER_SYNC_END_REG_NUM, {{CR5F, 0, 4} } }
241};
242
243static struct rgbLUT palLUT_table[] = {
244 /* {R,G,B} */
245 /* Index 0x00~0x03 */
246 {0x00, 0x00, 0x00}, {0x00, 0x00, 0x2A}, {0x00, 0x2A, 0x00}, {0x00,
247 0x2A,
248 0x2A},
249 /* Index 0x04~0x07 */
250 {0x2A, 0x00, 0x00}, {0x2A, 0x00, 0x2A}, {0x2A, 0x15, 0x00}, {0x2A,
251 0x2A,
252 0x2A},
253 /* Index 0x08~0x0B */
254 {0x15, 0x15, 0x15}, {0x15, 0x15, 0x3F}, {0x15, 0x3F, 0x15}, {0x15,
255 0x3F,
256 0x3F},
257 /* Index 0x0C~0x0F */
258 {0x3F, 0x15, 0x15}, {0x3F, 0x15, 0x3F}, {0x3F, 0x3F, 0x15}, {0x3F,
259 0x3F,
260 0x3F},
261 /* Index 0x10~0x13 */
262 {0x00, 0x00, 0x00}, {0x05, 0x05, 0x05}, {0x08, 0x08, 0x08}, {0x0B,
263 0x0B,
264 0x0B},
265 /* Index 0x14~0x17 */
266 {0x0E, 0x0E, 0x0E}, {0x11, 0x11, 0x11}, {0x14, 0x14, 0x14}, {0x18,
267 0x18,
268 0x18},
269 /* Index 0x18~0x1B */
270 {0x1C, 0x1C, 0x1C}, {0x20, 0x20, 0x20}, {0x24, 0x24, 0x24}, {0x28,
271 0x28,
272 0x28},
273 /* Index 0x1C~0x1F */
274 {0x2D, 0x2D, 0x2D}, {0x32, 0x32, 0x32}, {0x38, 0x38, 0x38}, {0x3F,
275 0x3F,
276 0x3F},
277 /* Index 0x20~0x23 */
278 {0x00, 0x00, 0x3F}, {0x10, 0x00, 0x3F}, {0x1F, 0x00, 0x3F}, {0x2F,
279 0x00,
280 0x3F},
281 /* Index 0x24~0x27 */
282 {0x3F, 0x00, 0x3F}, {0x3F, 0x00, 0x2F}, {0x3F, 0x00, 0x1F}, {0x3F,
283 0x00,
284 0x10},
285 /* Index 0x28~0x2B */
286 {0x3F, 0x00, 0x00}, {0x3F, 0x10, 0x00}, {0x3F, 0x1F, 0x00}, {0x3F,
287 0x2F,
288 0x00},
289 /* Index 0x2C~0x2F */
290 {0x3F, 0x3F, 0x00}, {0x2F, 0x3F, 0x00}, {0x1F, 0x3F, 0x00}, {0x10,
291 0x3F,
292 0x00},
293 /* Index 0x30~0x33 */
294 {0x00, 0x3F, 0x00}, {0x00, 0x3F, 0x10}, {0x00, 0x3F, 0x1F}, {0x00,
295 0x3F,
296 0x2F},
297 /* Index 0x34~0x37 */
298 {0x00, 0x3F, 0x3F}, {0x00, 0x2F, 0x3F}, {0x00, 0x1F, 0x3F}, {0x00,
299 0x10,
300 0x3F},
301 /* Index 0x38~0x3B */
302 {0x1F, 0x1F, 0x3F}, {0x27, 0x1F, 0x3F}, {0x2F, 0x1F, 0x3F}, {0x37,
303 0x1F,
304 0x3F},
305 /* Index 0x3C~0x3F */
306 {0x3F, 0x1F, 0x3F}, {0x3F, 0x1F, 0x37}, {0x3F, 0x1F, 0x2F}, {0x3F,
307 0x1F,
308 0x27},
309 /* Index 0x40~0x43 */
310 {0x3F, 0x1F, 0x1F}, {0x3F, 0x27, 0x1F}, {0x3F, 0x2F, 0x1F}, {0x3F,
311 0x3F,
312 0x1F},
313 /* Index 0x44~0x47 */
314 {0x3F, 0x3F, 0x1F}, {0x37, 0x3F, 0x1F}, {0x2F, 0x3F, 0x1F}, {0x27,
315 0x3F,
316 0x1F},
317 /* Index 0x48~0x4B */
318 {0x1F, 0x3F, 0x1F}, {0x1F, 0x3F, 0x27}, {0x1F, 0x3F, 0x2F}, {0x1F,
319 0x3F,
320 0x37},
321 /* Index 0x4C~0x4F */
322 {0x1F, 0x3F, 0x3F}, {0x1F, 0x37, 0x3F}, {0x1F, 0x2F, 0x3F}, {0x1F,
323 0x27,
324 0x3F},
325 /* Index 0x50~0x53 */
326 {0x2D, 0x2D, 0x3F}, {0x31, 0x2D, 0x3F}, {0x36, 0x2D, 0x3F}, {0x3A,
327 0x2D,
328 0x3F},
329 /* Index 0x54~0x57 */
330 {0x3F, 0x2D, 0x3F}, {0x3F, 0x2D, 0x3A}, {0x3F, 0x2D, 0x36}, {0x3F,
331 0x2D,
332 0x31},
333 /* Index 0x58~0x5B */
334 {0x3F, 0x2D, 0x2D}, {0x3F, 0x31, 0x2D}, {0x3F, 0x36, 0x2D}, {0x3F,
335 0x3A,
336 0x2D},
337 /* Index 0x5C~0x5F */
338 {0x3F, 0x3F, 0x2D}, {0x3A, 0x3F, 0x2D}, {0x36, 0x3F, 0x2D}, {0x31,
339 0x3F,
340 0x2D},
341 /* Index 0x60~0x63 */
342 {0x2D, 0x3F, 0x2D}, {0x2D, 0x3F, 0x31}, {0x2D, 0x3F, 0x36}, {0x2D,
343 0x3F,
344 0x3A},
345 /* Index 0x64~0x67 */
346 {0x2D, 0x3F, 0x3F}, {0x2D, 0x3A, 0x3F}, {0x2D, 0x36, 0x3F}, {0x2D,
347 0x31,
348 0x3F},
349 /* Index 0x68~0x6B */
350 {0x00, 0x00, 0x1C}, {0x07, 0x00, 0x1C}, {0x0E, 0x00, 0x1C}, {0x15,
351 0x00,
352 0x1C},
353 /* Index 0x6C~0x6F */
354 {0x1C, 0x00, 0x1C}, {0x1C, 0x00, 0x15}, {0x1C, 0x00, 0x0E}, {0x1C,
355 0x00,
356 0x07},
357 /* Index 0x70~0x73 */
358 {0x1C, 0x00, 0x00}, {0x1C, 0x07, 0x00}, {0x1C, 0x0E, 0x00}, {0x1C,
359 0x15,
360 0x00},
361 /* Index 0x74~0x77 */
362 {0x1C, 0x1C, 0x00}, {0x15, 0x1C, 0x00}, {0x0E, 0x1C, 0x00}, {0x07,
363 0x1C,
364 0x00},
365 /* Index 0x78~0x7B */
366 {0x00, 0x1C, 0x00}, {0x00, 0x1C, 0x07}, {0x00, 0x1C, 0x0E}, {0x00,
367 0x1C,
368 0x15},
369 /* Index 0x7C~0x7F */
370 {0x00, 0x1C, 0x1C}, {0x00, 0x15, 0x1C}, {0x00, 0x0E, 0x1C}, {0x00,
371 0x07,
372 0x1C},
373 /* Index 0x80~0x83 */
374 {0x0E, 0x0E, 0x1C}, {0x11, 0x0E, 0x1C}, {0x15, 0x0E, 0x1C}, {0x18,
375 0x0E,
376 0x1C},
377 /* Index 0x84~0x87 */
378 {0x1C, 0x0E, 0x1C}, {0x1C, 0x0E, 0x18}, {0x1C, 0x0E, 0x15}, {0x1C,
379 0x0E,
380 0x11},
381 /* Index 0x88~0x8B */
382 {0x1C, 0x0E, 0x0E}, {0x1C, 0x11, 0x0E}, {0x1C, 0x15, 0x0E}, {0x1C,
383 0x18,
384 0x0E},
385 /* Index 0x8C~0x8F */
386 {0x1C, 0x1C, 0x0E}, {0x18, 0x1C, 0x0E}, {0x15, 0x1C, 0x0E}, {0x11,
387 0x1C,
388 0x0E},
389 /* Index 0x90~0x93 */
390 {0x0E, 0x1C, 0x0E}, {0x0E, 0x1C, 0x11}, {0x0E, 0x1C, 0x15}, {0x0E,
391 0x1C,
392 0x18},
393 /* Index 0x94~0x97 */
394 {0x0E, 0x1C, 0x1C}, {0x0E, 0x18, 0x1C}, {0x0E, 0x15, 0x1C}, {0x0E,
395 0x11,
396 0x1C},
397 /* Index 0x98~0x9B */
398 {0x14, 0x14, 0x1C}, {0x16, 0x14, 0x1C}, {0x18, 0x14, 0x1C}, {0x1A,
399 0x14,
400 0x1C},
401 /* Index 0x9C~0x9F */
402 {0x1C, 0x14, 0x1C}, {0x1C, 0x14, 0x1A}, {0x1C, 0x14, 0x18}, {0x1C,
403 0x14,
404 0x16},
405 /* Index 0xA0~0xA3 */
406 {0x1C, 0x14, 0x14}, {0x1C, 0x16, 0x14}, {0x1C, 0x18, 0x14}, {0x1C,
407 0x1A,
408 0x14},
409 /* Index 0xA4~0xA7 */
410 {0x1C, 0x1C, 0x14}, {0x1A, 0x1C, 0x14}, {0x18, 0x1C, 0x14}, {0x16,
411 0x1C,
412 0x14},
413 /* Index 0xA8~0xAB */
414 {0x14, 0x1C, 0x14}, {0x14, 0x1C, 0x16}, {0x14, 0x1C, 0x18}, {0x14,
415 0x1C,
416 0x1A},
417 /* Index 0xAC~0xAF */
418 {0x14, 0x1C, 0x1C}, {0x14, 0x1A, 0x1C}, {0x14, 0x18, 0x1C}, {0x14,
419 0x16,
420 0x1C},
421 /* Index 0xB0~0xB3 */
422 {0x00, 0x00, 0x10}, {0x04, 0x00, 0x10}, {0x08, 0x00, 0x10}, {0x0C,
423 0x00,
424 0x10},
425 /* Index 0xB4~0xB7 */
426 {0x10, 0x00, 0x10}, {0x10, 0x00, 0x0C}, {0x10, 0x00, 0x08}, {0x10,
427 0x00,
428 0x04},
429 /* Index 0xB8~0xBB */
430 {0x10, 0x00, 0x00}, {0x10, 0x04, 0x00}, {0x10, 0x08, 0x00}, {0x10,
431 0x0C,
432 0x00},
433 /* Index 0xBC~0xBF */
434 {0x10, 0x10, 0x00}, {0x0C, 0x10, 0x00}, {0x08, 0x10, 0x00}, {0x04,
435 0x10,
436 0x00},
437 /* Index 0xC0~0xC3 */
438 {0x00, 0x10, 0x00}, {0x00, 0x10, 0x04}, {0x00, 0x10, 0x08}, {0x00,
439 0x10,
440 0x0C},
441 /* Index 0xC4~0xC7 */
442 {0x00, 0x10, 0x10}, {0x00, 0x0C, 0x10}, {0x00, 0x08, 0x10}, {0x00,
443 0x04,
444 0x10},
445 /* Index 0xC8~0xCB */
446 {0x08, 0x08, 0x10}, {0x0A, 0x08, 0x10}, {0x0C, 0x08, 0x10}, {0x0E,
447 0x08,
448 0x10},
449 /* Index 0xCC~0xCF */
450 {0x10, 0x08, 0x10}, {0x10, 0x08, 0x0E}, {0x10, 0x08, 0x0C}, {0x10,
451 0x08,
452 0x0A},
453 /* Index 0xD0~0xD3 */
454 {0x10, 0x08, 0x08}, {0x10, 0x0A, 0x08}, {0x10, 0x0C, 0x08}, {0x10,
455 0x0E,
456 0x08},
457 /* Index 0xD4~0xD7 */
458 {0x10, 0x10, 0x08}, {0x0E, 0x10, 0x08}, {0x0C, 0x10, 0x08}, {0x0A,
459 0x10,
460 0x08},
461 /* Index 0xD8~0xDB */
462 {0x08, 0x10, 0x08}, {0x08, 0x10, 0x0A}, {0x08, 0x10, 0x0C}, {0x08,
463 0x10,
464 0x0E},
465 /* Index 0xDC~0xDF */
466 {0x08, 0x10, 0x10}, {0x08, 0x0E, 0x10}, {0x08, 0x0C, 0x10}, {0x08,
467 0x0A,
468 0x10},
469 /* Index 0xE0~0xE3 */
470 {0x0B, 0x0B, 0x10}, {0x0C, 0x0B, 0x10}, {0x0D, 0x0B, 0x10}, {0x0F,
471 0x0B,
472 0x10},
473 /* Index 0xE4~0xE7 */
474 {0x10, 0x0B, 0x10}, {0x10, 0x0B, 0x0F}, {0x10, 0x0B, 0x0D}, {0x10,
475 0x0B,
476 0x0C},
477 /* Index 0xE8~0xEB */
478 {0x10, 0x0B, 0x0B}, {0x10, 0x0C, 0x0B}, {0x10, 0x0D, 0x0B}, {0x10,
479 0x0F,
480 0x0B},
481 /* Index 0xEC~0xEF */
482 {0x10, 0x10, 0x0B}, {0x0F, 0x10, 0x0B}, {0x0D, 0x10, 0x0B}, {0x0C,
483 0x10,
484 0x0B},
485 /* Index 0xF0~0xF3 */
486 {0x0B, 0x10, 0x0B}, {0x0B, 0x10, 0x0C}, {0x0B, 0x10, 0x0D}, {0x0B,
487 0x10,
488 0x0F},
489 /* Index 0xF4~0xF7 */
490 {0x0B, 0x10, 0x10}, {0x0B, 0x0F, 0x10}, {0x0B, 0x0D, 0x10}, {0x0B,
491 0x0C,
492 0x10},
493 /* Index 0xF8~0xFB */
494 {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00,
495 0x00,
496 0x00},
497 /* Index 0xFC~0xFF */
498 {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00,
499 0x00,
500 0x00}
501};
502
503static void set_crt_output_path(int set_iga);
504static void dvi_patch_skew_dvp0(void);
505static void dvi_patch_skew_dvp1(void);
506static void dvi_patch_skew_dvp_low(void);
507static void set_dvi_output_path(int set_iga, int output_interface);
508static void set_lcd_output_path(int set_iga, int output_interface);
509static int search_mode_setting(int ModeInfoIndex);
510static void load_fix_bit_crtc_reg(void);
511static void init_gfx_chip_info(void);
512static void init_tmds_chip_info(void);
513static void init_lvds_chip_info(void);
514static void device_screen_off(void);
515static void device_screen_on(void);
516static void set_display_channel(void);
517static void device_off(void);
518static void device_on(void);
519static void enable_second_display_channel(void);
520static void disable_second_display_channel(void);
521static int get_fb_size_from_pci(void);
522
523void viafb_write_reg(u8 index, u16 io_port, u8 data)
524{
525 outb(index, io_port);
526 outb(data, io_port + 1);
527 /*DEBUG_MSG(KERN_INFO "\nIndex=%2d Value=%2d", index, data); */
528}
529u8 viafb_read_reg(int io_port, u8 index)
530{
531 outb(index, io_port);
532 return inb(io_port + 1);
533}
534
535void viafb_lock_crt(void)
536{
537 viafb_write_reg_mask(CR11, VIACR, BIT7, BIT7);
538}
539
540void viafb_unlock_crt(void)
541{
542 viafb_write_reg_mask(CR11, VIACR, 0, BIT7);
543 viafb_write_reg_mask(CR47, VIACR, 0, BIT0);
544}
545
546void viafb_write_reg_mask(u8 index, int io_port, u8 data, u8 mask)
547{
548 u8 tmp;
549
550 outb(index, io_port);
551 tmp = inb(io_port + 1);
552 outb((data & mask) | (tmp & (~mask)), io_port + 1);
553 /*DEBUG_MSG(KERN_INFO "\nIndex=%2d Value=%2d", index, tmp); */
554}
555
556void write_dac_reg(u8 index, u8 r, u8 g, u8 b)
557{
558 outb(index, LUT_INDEX_WRITE);
559 outb(r, LUT_DATA);
560 outb(g, LUT_DATA);
561 outb(b, LUT_DATA);
562}
563
564/*Set IGA path for each device*/
565void viafb_set_iga_path(void)
566{
567
568 if (viafb_SAMM_ON == 1) {
569 if (viafb_CRT_ON) {
570 if (viafb_primary_dev == CRT_Device)
571 viaparinfo->crt_setting_info->iga_path = IGA1;
572 else
573 viaparinfo->crt_setting_info->iga_path = IGA2;
574 }
575
576 if (viafb_DVI_ON) {
577 if (viafb_primary_dev == DVI_Device)
578 viaparinfo->tmds_setting_info->iga_path = IGA1;
579 else
580 viaparinfo->tmds_setting_info->iga_path = IGA2;
581 }
582
583 if (viafb_LCD_ON) {
584 if (viafb_primary_dev == LCD_Device) {
585 if (viafb_dual_fb &&
586 (viaparinfo->chip_info->gfx_chip_name ==
587 UNICHROME_CLE266)) {
588 viaparinfo->
589 lvds_setting_info->iga_path = IGA2;
590 viaparinfo->
591 crt_setting_info->iga_path = IGA1;
592 viaparinfo->
593 tmds_setting_info->iga_path = IGA1;
594 } else
595 viaparinfo->
596 lvds_setting_info->iga_path = IGA1;
597 } else {
598 viaparinfo->lvds_setting_info->iga_path = IGA2;
599 }
600 }
601 if (viafb_LCD2_ON) {
602 if (LCD2_Device == viafb_primary_dev)
603 viaparinfo->lvds_setting_info2->iga_path = IGA1;
604 else
605 viaparinfo->lvds_setting_info2->iga_path = IGA2;
606 }
607 } else {
608 viafb_SAMM_ON = 0;
609
610 if (viafb_CRT_ON && viafb_LCD_ON) {
611 viaparinfo->crt_setting_info->iga_path = IGA1;
612 viaparinfo->lvds_setting_info->iga_path = IGA2;
613 } else if (viafb_CRT_ON && viafb_DVI_ON) {
614 viaparinfo->crt_setting_info->iga_path = IGA1;
615 viaparinfo->tmds_setting_info->iga_path = IGA2;
616 } else if (viafb_LCD_ON && viafb_DVI_ON) {
617 viaparinfo->tmds_setting_info->iga_path = IGA1;
618 viaparinfo->lvds_setting_info->iga_path = IGA2;
619 } else if (viafb_LCD_ON && viafb_LCD2_ON) {
620 viaparinfo->lvds_setting_info->iga_path = IGA2;
621 viaparinfo->lvds_setting_info2->iga_path = IGA2;
622 } else if (viafb_CRT_ON) {
623 viaparinfo->crt_setting_info->iga_path = IGA1;
624 } else if (viafb_LCD_ON) {
625 viaparinfo->lvds_setting_info->iga_path = IGA2;
626 } else if (viafb_DVI_ON) {
627 viaparinfo->tmds_setting_info->iga_path = IGA1;
628 }
629 }
630}
631
632void viafb_set_start_addr(void)
633{
634 unsigned long offset = 0, tmp = 0, size = 0;
635 unsigned long length;
636
637 DEBUG_MSG(KERN_INFO "viafb_set_start_addr!\n");
638 viafb_unlock_crt();
639 /* update starting address of IGA1 */
640 viafb_write_reg(CR0C, VIACR, 0x00); /*initial starting address */
641 viafb_write_reg(CR0D, VIACR, 0x00);
642 viafb_write_reg(CR34, VIACR, 0x00);
643 viafb_write_reg_mask(CR48, VIACR, 0x00, 0x1F);
644
645 if (viafb_dual_fb) {
646 viaparinfo->iga_path = IGA1;
647 viaparinfo1->iga_path = IGA2;
648 }
649
650 if (viafb_SAMM_ON == 1) {
651 if (!viafb_dual_fb) {
652 if (viafb_second_size)
653 size = viafb_second_size * 1024 * 1024;
654 else
655 size = 8 * 1024 * 1024;
656 } else {
657
658 size = viaparinfo1->memsize;
659 }
660 offset = viafb_second_offset;
661 DEBUG_MSG(KERN_INFO
662 "viafb_second_size=%lx, second start_adddress=%lx\n",
663 size, offset);
664 }
665 if (viafb_SAMM_ON == 1) {
666 offset = offset >> 3;
667
668 tmp = viafb_read_reg(VIACR, 0x62) & 0x01;
669 tmp |= (offset & 0x7F) << 1;
670 viafb_write_reg(CR62, VIACR, tmp);
671 viafb_write_reg(CR63, VIACR, ((offset & 0x7F80) >> 7));
672 viafb_write_reg(CR64, VIACR, ((offset & 0x7F8000) >> 15));
673 viafb_write_reg(CRA3, VIACR, ((offset & 0x3800000) >> 23));
674 } else {
675 /* update starting address */
676 viafb_write_reg(CR62, VIACR, 0x00);
677 viafb_write_reg(CR63, VIACR, 0x00);
678 viafb_write_reg(CR64, VIACR, 0x00);
679 viafb_write_reg(CRA3, VIACR, 0x00);
680 }
681
682 if (viafb_SAMM_ON == 1) {
683 if (viafb_accel) {
684 if (!viafb_dual_fb)
685 length = size - viaparinfo->fbmem_used;
686 else
687 length = size - viaparinfo1->fbmem_used;
688 } else
689 length = size;
690 offset = (unsigned long)(void *)viafb_FB_MM +
691 viafb_second_offset;
692 memset((void *)offset, 0, length);
693 }
694
695 viafb_lock_crt();
696}
697
698void viafb_set_output_path(int device, int set_iga, int output_interface)
699{
700 switch (device) {
701 case DEVICE_CRT:
702 set_crt_output_path(set_iga);
703 break;
704 case DEVICE_DVI:
705 set_dvi_output_path(set_iga, output_interface);
706 break;
707 case DEVICE_LCD:
708 set_lcd_output_path(set_iga, output_interface);
709 break;
710 }
711}
712
713static void set_crt_output_path(int set_iga)
714{
715 viafb_write_reg_mask(CR36, VIACR, 0x00, BIT4 + BIT5);
716
717 switch (set_iga) {
718 case IGA1:
719 viafb_write_reg_mask(SR16, VIASR, 0x00, BIT6);
720 break;
721 case IGA2:
722 case IGA1_IGA2:
723 viafb_write_reg_mask(CR6A, VIACR, 0xC0, BIT6 + BIT7);
724 viafb_write_reg_mask(SR16, VIASR, 0x40, BIT6);
725 if (set_iga == IGA1_IGA2)
726 viafb_write_reg_mask(CR6B, VIACR, 0x08, BIT3);
727 break;
728 }
729}
730
731static void dvi_patch_skew_dvp0(void)
732{
733 /* Reset data driving first: */
734 viafb_write_reg_mask(SR1B, VIASR, 0, BIT1);
735 viafb_write_reg_mask(SR2A, VIASR, 0, BIT4);
736
737 switch (viaparinfo->chip_info->gfx_chip_name) {
738 case UNICHROME_P4M890:
739 {
740 if ((viaparinfo->tmds_setting_info->h_active == 1600) &&
741 (viaparinfo->tmds_setting_info->v_active ==
742 1200))
743 viafb_write_reg_mask(CR96, VIACR, 0x03,
744 BIT0 + BIT1 + BIT2);
745 else
746 viafb_write_reg_mask(CR96, VIACR, 0x07,
747 BIT0 + BIT1 + BIT2);
748 break;
749 }
750
751 case UNICHROME_P4M900:
752 {
753 viafb_write_reg_mask(CR96, VIACR, 0x07,
754 BIT0 + BIT1 + BIT2 + BIT3);
755 viafb_write_reg_mask(SR1B, VIASR, 0x02, BIT1);
756 viafb_write_reg_mask(SR2A, VIASR, 0x10, BIT4);
757 break;
758 }
759
760 default:
761 {
762 break;
763 }
764 }
765}
766
767static void dvi_patch_skew_dvp1(void)
768{
769 switch (viaparinfo->chip_info->gfx_chip_name) {
770 case UNICHROME_CX700:
771 {
772 break;
773 }
774
775 default:
776 {
777 break;
778 }
779 }
780}
781
782static void dvi_patch_skew_dvp_low(void)
783{
784 switch (viaparinfo->chip_info->gfx_chip_name) {
785 case UNICHROME_K8M890:
786 {
787 viafb_write_reg_mask(CR99, VIACR, 0x03, BIT0 + BIT1);
788 break;
789 }
790
791 case UNICHROME_P4M900:
792 {
793 viafb_write_reg_mask(CR99, VIACR, 0x08,
794 BIT0 + BIT1 + BIT2 + BIT3);
795 break;
796 }
797
798 case UNICHROME_P4M890:
799 {
800 viafb_write_reg_mask(CR99, VIACR, 0x0F,
801 BIT0 + BIT1 + BIT2 + BIT3);
802 break;
803 }
804
805 default:
806 {
807 break;
808 }
809 }
810}
811
812static void set_dvi_output_path(int set_iga, int output_interface)
813{
814 switch (output_interface) {
815 case INTERFACE_DVP0:
816 viafb_write_reg_mask(CR6B, VIACR, 0x01, BIT0);
817
818 if (set_iga == IGA1) {
819 viafb_write_reg_mask(CR96, VIACR, 0x00, BIT4);
820 viafb_write_reg_mask(CR6C, VIACR, 0x21, BIT0 +
821 BIT5 + BIT7);
822 } else {
823 viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4);
824 viafb_write_reg_mask(CR6C, VIACR, 0xA1, BIT0 +
825 BIT5 + BIT7);
826 }
827
828 viafb_write_reg_mask(SR1E, VIASR, 0xC0, BIT7 + BIT6);
829
830 dvi_patch_skew_dvp0();
831 break;
832
833 case INTERFACE_DVP1:
834 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
835 if (set_iga == IGA1)
836 viafb_write_reg_mask(CR93, VIACR, 0x21,
837 BIT0 + BIT5 + BIT7);
838 else
839 viafb_write_reg_mask(CR93, VIACR, 0xA1,
840 BIT0 + BIT5 + BIT7);
841 } else {
842 if (set_iga == IGA1)
843 viafb_write_reg_mask(CR9B, VIACR, 0x00, BIT4);
844 else
845 viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4);
846 }
847
848 viafb_write_reg_mask(SR1E, VIASR, 0x30, BIT4 + BIT5);
849 dvi_patch_skew_dvp1();
850 break;
851 case INTERFACE_DFP_HIGH:
852 if (viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266) {
853 if (set_iga == IGA1) {
854 viafb_write_reg_mask(CR96, VIACR, 0x00, BIT4);
855 viafb_write_reg_mask(CR97, VIACR, 0x03,
856 BIT0 + BIT1 + BIT4);
857 } else {
858 viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4);
859 viafb_write_reg_mask(CR97, VIACR, 0x13,
860 BIT0 + BIT1 + BIT4);
861 }
862 }
863 viafb_write_reg_mask(SR2A, VIASR, 0x0C, BIT2 + BIT3);
864 break;
865
866 case INTERFACE_DFP_LOW:
867 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
868 break;
869
870 if (set_iga == IGA1) {
871 viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4);
872 viafb_write_reg_mask(CR9B, VIACR, 0x00, BIT4);
873 } else {
874 viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4);
875 viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4);
876 }
877
878 viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1);
879 dvi_patch_skew_dvp_low();
880 break;
881
882 case INTERFACE_TMDS:
883 if (set_iga == IGA1)
884 viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4);
885 else
886 viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4);
887 break;
888 }
889
890 if (set_iga == IGA2) {
891 enable_second_display_channel();
892 /* Disable LCD Scaling */
893 viafb_write_reg_mask(CR79, VIACR, 0x00, BIT0);
894 }
895}
896
897static void set_lcd_output_path(int set_iga, int output_interface)
898{
899 DEBUG_MSG(KERN_INFO
900 "set_lcd_output_path, iga:%d,out_interface:%d\n",
901 set_iga, output_interface);
902 switch (set_iga) {
903 case IGA1:
904 viafb_write_reg_mask(CR6B, VIACR, 0x00, BIT3);
905 viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3);
906
907 disable_second_display_channel();
908 break;
909
910 case IGA2:
911 viafb_write_reg_mask(CR6B, VIACR, 0x00, BIT3);
912 viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3);
913
914 enable_second_display_channel();
915 break;
916
917 case IGA1_IGA2:
918 viafb_write_reg_mask(CR6B, VIACR, 0x08, BIT3);
919 viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3);
920
921 disable_second_display_channel();
922 break;
923 }
924
925 switch (output_interface) {
926 case INTERFACE_DVP0:
927 if (set_iga == IGA1) {
928 viafb_write_reg_mask(CR96, VIACR, 0x00, BIT4);
929 } else {
930 viafb_write_reg(CR91, VIACR, 0x00);
931 viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4);
932 }
933 break;
934
935 case INTERFACE_DVP1:
936 if (set_iga == IGA1)
937 viafb_write_reg_mask(CR9B, VIACR, 0x00, BIT4);
938 else {
939 viafb_write_reg(CR91, VIACR, 0x00);
940 viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4);
941 }
942 break;
943
944 case INTERFACE_DFP_HIGH:
945 if (set_iga == IGA1)
946 viafb_write_reg_mask(CR97, VIACR, 0x00, BIT4);
947 else {
948 viafb_write_reg(CR91, VIACR, 0x00);
949 viafb_write_reg_mask(CR97, VIACR, 0x10, BIT4);
950 viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4);
951 }
952 break;
953
954 case INTERFACE_DFP_LOW:
955 if (set_iga == IGA1)
956 viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4);
957 else {
958 viafb_write_reg(CR91, VIACR, 0x00);
959 viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4);
960 viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4);
961 }
962
963 break;
964
965 case INTERFACE_DFP:
966 if ((UNICHROME_K8M890 == viaparinfo->chip_info->gfx_chip_name)
967 || (UNICHROME_P4M890 ==
968 viaparinfo->chip_info->gfx_chip_name))
969 viafb_write_reg_mask(CR97, VIACR, 0x84,
970 BIT7 + BIT2 + BIT1 + BIT0);
971 if (set_iga == IGA1) {
972 viafb_write_reg_mask(CR97, VIACR, 0x00, BIT4);
973 viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4);
974 } else {
975 viafb_write_reg(CR91, VIACR, 0x00);
976 viafb_write_reg_mask(CR97, VIACR, 0x10, BIT4);
977 viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4);
978 }
979 break;
980
981 case INTERFACE_LVDS0:
982 case INTERFACE_LVDS0LVDS1:
983 if (set_iga == IGA1)
984 viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4);
985 else
986 viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4);
987
988 break;
989
990 case INTERFACE_LVDS1:
991 if (set_iga == IGA1)
992 viafb_write_reg_mask(CR97, VIACR, 0x00, BIT4);
993 else
994 viafb_write_reg_mask(CR97, VIACR, 0x10, BIT4);
995 break;
996 }
997}
998
999/* Search Mode Index */
1000static int search_mode_setting(int ModeInfoIndex)
1001{
1002 int i = 0;
1003
1004 while ((i < NUM_TOTAL_MODETABLE) &&
1005 (ModeInfoIndex != CLE266Modes[i].ModeIndex))
1006 i++;
1007 if (i >= NUM_TOTAL_MODETABLE)
1008 i = 0;
1009 return i;
1010
1011}
1012
1013struct VideoModeTable *viafb_get_modetbl_pointer(int Index)
1014{
1015 struct VideoModeTable *TmpTbl = NULL;
1016 TmpTbl = &CLE266Modes[search_mode_setting(Index)];
1017 return TmpTbl;
1018}
1019
1020struct VideoModeTable *viafb_get_cea_mode_tbl_pointer(int Index)
1021{
1022 struct VideoModeTable *TmpTbl = NULL;
1023 int i = 0;
1024 while ((i < NUM_TOTAL_CEA_MODES) &&
1025 (Index != CEA_HDMI_Modes[i].ModeIndex))
1026 i++;
1027 if ((i < NUM_TOTAL_CEA_MODES))
1028 TmpTbl = &CEA_HDMI_Modes[i];
1029 else {
1030 /*Still use general timing if don't find CEA timing */
1031 i = 0;
1032 while ((i < NUM_TOTAL_MODETABLE) &&
1033 (Index != CLE266Modes[i].ModeIndex))
1034 i++;
1035 if (i >= NUM_TOTAL_MODETABLE)
1036 i = 0;
1037 TmpTbl = &CLE266Modes[i];
1038 }
1039 return TmpTbl;
1040}
1041
1042static void load_fix_bit_crtc_reg(void)
1043{
1044 /* always set to 1 */
1045 viafb_write_reg_mask(CR03, VIACR, 0x80, BIT7);
1046 /* line compare should set all bits = 1 (extend modes) */
1047 viafb_write_reg(CR18, VIACR, 0xff);
1048 /* line compare should set all bits = 1 (extend modes) */
1049 viafb_write_reg_mask(CR07, VIACR, 0x10, BIT4);
1050 /* line compare should set all bits = 1 (extend modes) */
1051 viafb_write_reg_mask(CR09, VIACR, 0x40, BIT6);
1052 /* line compare should set all bits = 1 (extend modes) */
1053 viafb_write_reg_mask(CR35, VIACR, 0x10, BIT4);
1054 /* line compare should set all bits = 1 (extend modes) */
1055 viafb_write_reg_mask(CR33, VIACR, 0x06, BIT0 + BIT1 + BIT2);
1056 /*viafb_write_reg_mask(CR32, VIACR, 0x01, BIT0); */
1057 /* extend mode always set to e3h */
1058 viafb_write_reg(CR17, VIACR, 0xe3);
1059 /* extend mode always set to 0h */
1060 viafb_write_reg(CR08, VIACR, 0x00);
1061 /* extend mode always set to 0h */
1062 viafb_write_reg(CR14, VIACR, 0x00);
1063
1064 /* If K8M800, enable Prefetch Mode. */
1065 if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800)
1066 || (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K8M890))
1067 viafb_write_reg_mask(CR33, VIACR, 0x08, BIT3);
1068 if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
1069 && (viaparinfo->chip_info->gfx_chip_revision == CLE266_REVISION_AX))
1070 viafb_write_reg_mask(SR1A, VIASR, 0x02, BIT1);
1071
1072}
1073
1074void viafb_load_reg(int timing_value, int viafb_load_reg_num,
1075 struct io_register *reg,
1076 int io_type)
1077{
1078 int reg_mask;
1079 int bit_num = 0;
1080 int data;
1081 int i, j;
1082 int shift_next_reg;
1083 int start_index, end_index, cr_index;
1084 u16 get_bit;
1085
1086 for (i = 0; i < viafb_load_reg_num; i++) {
1087 reg_mask = 0;
1088 data = 0;
1089 start_index = reg[i].start_bit;
1090 end_index = reg[i].end_bit;
1091 cr_index = reg[i].io_addr;
1092
1093 shift_next_reg = bit_num;
1094 for (j = start_index; j <= end_index; j++) {
1095 /*if (bit_num==8) timing_value = timing_value >>8; */
1096 reg_mask = reg_mask | (BIT0 << j);
1097 get_bit = (timing_value & (BIT0 << bit_num));
1098 data =
1099 data | ((get_bit >> shift_next_reg) << start_index);
1100 bit_num++;
1101 }
1102 if (io_type == VIACR)
1103 viafb_write_reg_mask(cr_index, VIACR, data, reg_mask);
1104 else
1105 viafb_write_reg_mask(cr_index, VIASR, data, reg_mask);
1106 }
1107
1108}
1109
1110/* Write Registers */
1111void viafb_write_regx(struct io_reg RegTable[], int ItemNum)
1112{
1113 int i;
1114 unsigned char RegTemp;
1115
1116 /*DEBUG_MSG(KERN_INFO "Table Size : %x!!\n",ItemNum ); */
1117
1118 for (i = 0; i < ItemNum; i++) {
1119 outb(RegTable[i].index, RegTable[i].port);
1120 RegTemp = inb(RegTable[i].port + 1);
1121 RegTemp = (RegTemp & (~RegTable[i].mask)) | RegTable[i].value;
1122 outb(RegTemp, RegTable[i].port + 1);
1123 }
1124}
1125
1126void viafb_load_offset_reg(int h_addr, int bpp_byte, int set_iga)
1127{
1128 int reg_value;
1129 int viafb_load_reg_num;
1130 struct io_register *reg;
1131
1132 switch (set_iga) {
1133 case IGA1_IGA2:
1134 case IGA1:
1135 reg_value = IGA1_OFFSET_FORMULA(h_addr, bpp_byte);
1136 viafb_load_reg_num = offset_reg.iga1_offset_reg.reg_num;
1137 reg = offset_reg.iga1_offset_reg.reg;
1138 viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
1139 if (set_iga == IGA1)
1140 break;
1141 case IGA2:
1142 reg_value = IGA2_OFFSET_FORMULA(h_addr, bpp_byte);
1143 viafb_load_reg_num = offset_reg.iga2_offset_reg.reg_num;
1144 reg = offset_reg.iga2_offset_reg.reg;
1145 viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
1146 break;
1147 }
1148}
1149
1150void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga)
1151{
1152 int reg_value;
1153 int viafb_load_reg_num;
1154 struct io_register *reg = NULL;
1155
1156 switch (set_iga) {
1157 case IGA1_IGA2:
1158 case IGA1:
1159 reg_value = IGA1_FETCH_COUNT_FORMULA(h_addr, bpp_byte);
1160 viafb_load_reg_num = fetch_count_reg.
1161 iga1_fetch_count_reg.reg_num;
1162 reg = fetch_count_reg.iga1_fetch_count_reg.reg;
1163 viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
1164 if (set_iga == IGA1)
1165 break;
1166 case IGA2:
1167 reg_value = IGA2_FETCH_COUNT_FORMULA(h_addr, bpp_byte);
1168 viafb_load_reg_num = fetch_count_reg.
1169 iga2_fetch_count_reg.reg_num;
1170 reg = fetch_count_reg.iga2_fetch_count_reg.reg;
1171 viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
1172 break;
1173 }
1174
1175}
1176
1177void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active)
1178{
1179 int reg_value;
1180 int viafb_load_reg_num;
1181 struct io_register *reg = NULL;
1182 int iga1_fifo_max_depth = 0, iga1_fifo_threshold =
1183 0, iga1_fifo_high_threshold = 0, iga1_display_queue_expire_num = 0;
1184 int iga2_fifo_max_depth = 0, iga2_fifo_threshold =
1185 0, iga2_fifo_high_threshold = 0, iga2_display_queue_expire_num = 0;
1186
1187 if (set_iga == IGA1) {
1188 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) {
1189 iga1_fifo_max_depth = K800_IGA1_FIFO_MAX_DEPTH;
1190 iga1_fifo_threshold = K800_IGA1_FIFO_THRESHOLD;
1191 iga1_fifo_high_threshold =
1192 K800_IGA1_FIFO_HIGH_THRESHOLD;
1193 /* If resolution > 1280x1024, expire length = 64, else
1194 expire length = 128 */
1195 if ((hor_active > 1280) && (ver_active > 1024))
1196 iga1_display_queue_expire_num = 16;
1197 else
1198 iga1_display_queue_expire_num =
1199 K800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1200
1201 }
1202
1203 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_PM800) {
1204 iga1_fifo_max_depth = P880_IGA1_FIFO_MAX_DEPTH;
1205 iga1_fifo_threshold = P880_IGA1_FIFO_THRESHOLD;
1206 iga1_fifo_high_threshold =
1207 P880_IGA1_FIFO_HIGH_THRESHOLD;
1208 iga1_display_queue_expire_num =
1209 P880_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1210
1211 /* If resolution > 1280x1024, expire length = 64, else
1212 expire length = 128 */
1213 if ((hor_active > 1280) && (ver_active > 1024))
1214 iga1_display_queue_expire_num = 16;
1215 else
1216 iga1_display_queue_expire_num =
1217 P880_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1218 }
1219
1220 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CN700) {
1221 iga1_fifo_max_depth = CN700_IGA1_FIFO_MAX_DEPTH;
1222 iga1_fifo_threshold = CN700_IGA1_FIFO_THRESHOLD;
1223 iga1_fifo_high_threshold =
1224 CN700_IGA1_FIFO_HIGH_THRESHOLD;
1225
1226 /* If resolution > 1280x1024, expire length = 64,
1227 else expire length = 128 */
1228 if ((hor_active > 1280) && (ver_active > 1024))
1229 iga1_display_queue_expire_num = 16;
1230 else
1231 iga1_display_queue_expire_num =
1232 CN700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1233 }
1234
1235 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
1236 iga1_fifo_max_depth = CX700_IGA1_FIFO_MAX_DEPTH;
1237 iga1_fifo_threshold = CX700_IGA1_FIFO_THRESHOLD;
1238 iga1_fifo_high_threshold =
1239 CX700_IGA1_FIFO_HIGH_THRESHOLD;
1240 iga1_display_queue_expire_num =
1241 CX700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1242 }
1243
1244 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K8M890) {
1245 iga1_fifo_max_depth = K8M890_IGA1_FIFO_MAX_DEPTH;
1246 iga1_fifo_threshold = K8M890_IGA1_FIFO_THRESHOLD;
1247 iga1_fifo_high_threshold =
1248 K8M890_IGA1_FIFO_HIGH_THRESHOLD;
1249 iga1_display_queue_expire_num =
1250 K8M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1251 }
1252
1253 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M890) {
1254 iga1_fifo_max_depth = P4M890_IGA1_FIFO_MAX_DEPTH;
1255 iga1_fifo_threshold = P4M890_IGA1_FIFO_THRESHOLD;
1256 iga1_fifo_high_threshold =
1257 P4M890_IGA1_FIFO_HIGH_THRESHOLD;
1258 iga1_display_queue_expire_num =
1259 P4M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1260 }
1261
1262 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M900) {
1263 iga1_fifo_max_depth = P4M900_IGA1_FIFO_MAX_DEPTH;
1264 iga1_fifo_threshold = P4M900_IGA1_FIFO_THRESHOLD;
1265 iga1_fifo_high_threshold =
1266 P4M900_IGA1_FIFO_HIGH_THRESHOLD;
1267 iga1_display_queue_expire_num =
1268 P4M900_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1269 }
1270
1271 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX800) {
1272 iga1_fifo_max_depth = VX800_IGA1_FIFO_MAX_DEPTH;
1273 iga1_fifo_threshold = VX800_IGA1_FIFO_THRESHOLD;
1274 iga1_fifo_high_threshold =
1275 VX800_IGA1_FIFO_HIGH_THRESHOLD;
1276 iga1_display_queue_expire_num =
1277 VX800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1278 }
1279
1280 /* Set Display FIFO Depath Select */
1281 reg_value = IGA1_FIFO_DEPTH_SELECT_FORMULA(iga1_fifo_max_depth);
1282 viafb_load_reg_num =
1283 display_fifo_depth_reg.iga1_fifo_depth_select_reg.reg_num;
1284 reg = display_fifo_depth_reg.iga1_fifo_depth_select_reg.reg;
1285 viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
1286
1287 /* Set Display FIFO Threshold Select */
1288 reg_value = IGA1_FIFO_THRESHOLD_FORMULA(iga1_fifo_threshold);
1289 viafb_load_reg_num =
1290 fifo_threshold_select_reg.
1291 iga1_fifo_threshold_select_reg.reg_num;
1292 reg =
1293 fifo_threshold_select_reg.
1294 iga1_fifo_threshold_select_reg.reg;
1295 viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
1296
1297 /* Set FIFO High Threshold Select */
1298 reg_value =
1299 IGA1_FIFO_HIGH_THRESHOLD_FORMULA(iga1_fifo_high_threshold);
1300 viafb_load_reg_num =
1301 fifo_high_threshold_select_reg.
1302 iga1_fifo_high_threshold_select_reg.reg_num;
1303 reg =
1304 fifo_high_threshold_select_reg.
1305 iga1_fifo_high_threshold_select_reg.reg;
1306 viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
1307
1308 /* Set Display Queue Expire Num */
1309 reg_value =
1310 IGA1_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA
1311 (iga1_display_queue_expire_num);
1312 viafb_load_reg_num =
1313 display_queue_expire_num_reg.
1314 iga1_display_queue_expire_num_reg.reg_num;
1315 reg =
1316 display_queue_expire_num_reg.
1317 iga1_display_queue_expire_num_reg.reg;
1318 viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
1319
1320 } else {
1321 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) {
1322 iga2_fifo_max_depth = K800_IGA2_FIFO_MAX_DEPTH;
1323 iga2_fifo_threshold = K800_IGA2_FIFO_THRESHOLD;
1324 iga2_fifo_high_threshold =
1325 K800_IGA2_FIFO_HIGH_THRESHOLD;
1326
1327 /* If resolution > 1280x1024, expire length = 64,
1328 else expire length = 128 */
1329 if ((hor_active > 1280) && (ver_active > 1024))
1330 iga2_display_queue_expire_num = 16;
1331 else
1332 iga2_display_queue_expire_num =
1333 K800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1334 }
1335
1336 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_PM800) {
1337 iga2_fifo_max_depth = P880_IGA2_FIFO_MAX_DEPTH;
1338 iga2_fifo_threshold = P880_IGA2_FIFO_THRESHOLD;
1339 iga2_fifo_high_threshold =
1340 P880_IGA2_FIFO_HIGH_THRESHOLD;
1341
1342 /* If resolution > 1280x1024, expire length = 64,
1343 else expire length = 128 */
1344 if ((hor_active > 1280) && (ver_active > 1024))
1345 iga2_display_queue_expire_num = 16;
1346 else
1347 iga2_display_queue_expire_num =
1348 P880_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1349 }
1350
1351 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CN700) {
1352 iga2_fifo_max_depth = CN700_IGA2_FIFO_MAX_DEPTH;
1353 iga2_fifo_threshold = CN700_IGA2_FIFO_THRESHOLD;
1354 iga2_fifo_high_threshold =
1355 CN700_IGA2_FIFO_HIGH_THRESHOLD;
1356
1357 /* If resolution > 1280x1024, expire length = 64,
1358 else expire length = 128 */
1359 if ((hor_active > 1280) && (ver_active > 1024))
1360 iga2_display_queue_expire_num = 16;
1361 else
1362 iga2_display_queue_expire_num =
1363 CN700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1364 }
1365
1366 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
1367 iga2_fifo_max_depth = CX700_IGA2_FIFO_MAX_DEPTH;
1368 iga2_fifo_threshold = CX700_IGA2_FIFO_THRESHOLD;
1369 iga2_fifo_high_threshold =
1370 CX700_IGA2_FIFO_HIGH_THRESHOLD;
1371 iga2_display_queue_expire_num =
1372 CX700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1373 }
1374
1375 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K8M890) {
1376 iga2_fifo_max_depth = K8M890_IGA2_FIFO_MAX_DEPTH;
1377 iga2_fifo_threshold = K8M890_IGA2_FIFO_THRESHOLD;
1378 iga2_fifo_high_threshold =
1379 K8M890_IGA2_FIFO_HIGH_THRESHOLD;
1380 iga2_display_queue_expire_num =
1381 K8M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1382 }
1383
1384 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M890) {
1385 iga2_fifo_max_depth = P4M890_IGA2_FIFO_MAX_DEPTH;
1386 iga2_fifo_threshold = P4M890_IGA2_FIFO_THRESHOLD;
1387 iga2_fifo_high_threshold =
1388 P4M890_IGA2_FIFO_HIGH_THRESHOLD;
1389 iga2_display_queue_expire_num =
1390 P4M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1391 }
1392
1393 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M900) {
1394 iga2_fifo_max_depth = P4M900_IGA2_FIFO_MAX_DEPTH;
1395 iga2_fifo_threshold = P4M900_IGA2_FIFO_THRESHOLD;
1396 iga2_fifo_high_threshold =
1397 P4M900_IGA2_FIFO_HIGH_THRESHOLD;
1398 iga2_display_queue_expire_num =
1399 P4M900_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1400 }
1401
1402 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX800) {
1403 iga2_fifo_max_depth = VX800_IGA2_FIFO_MAX_DEPTH;
1404 iga2_fifo_threshold = VX800_IGA2_FIFO_THRESHOLD;
1405 iga2_fifo_high_threshold =
1406 VX800_IGA2_FIFO_HIGH_THRESHOLD;
1407 iga2_display_queue_expire_num =
1408 VX800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1409 }
1410
1411 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) {
1412 /* Set Display FIFO Depath Select */
1413 reg_value =
1414 IGA2_FIFO_DEPTH_SELECT_FORMULA(iga2_fifo_max_depth)
1415 - 1;
1416 /* Patch LCD in IGA2 case */
1417 viafb_load_reg_num =
1418 display_fifo_depth_reg.
1419 iga2_fifo_depth_select_reg.reg_num;
1420 reg =
1421 display_fifo_depth_reg.
1422 iga2_fifo_depth_select_reg.reg;
1423 viafb_load_reg(reg_value,
1424 viafb_load_reg_num, reg, VIACR);
1425 } else {
1426
1427 /* Set Display FIFO Depath Select */
1428 reg_value =
1429 IGA2_FIFO_DEPTH_SELECT_FORMULA(iga2_fifo_max_depth);
1430 viafb_load_reg_num =
1431 display_fifo_depth_reg.
1432 iga2_fifo_depth_select_reg.reg_num;
1433 reg =
1434 display_fifo_depth_reg.
1435 iga2_fifo_depth_select_reg.reg;
1436 viafb_load_reg(reg_value,
1437 viafb_load_reg_num, reg, VIACR);
1438 }
1439
1440 /* Set Display FIFO Threshold Select */
1441 reg_value = IGA2_FIFO_THRESHOLD_FORMULA(iga2_fifo_threshold);
1442 viafb_load_reg_num =
1443 fifo_threshold_select_reg.
1444 iga2_fifo_threshold_select_reg.reg_num;
1445 reg =
1446 fifo_threshold_select_reg.
1447 iga2_fifo_threshold_select_reg.reg;
1448 viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
1449
1450 /* Set FIFO High Threshold Select */
1451 reg_value =
1452 IGA2_FIFO_HIGH_THRESHOLD_FORMULA(iga2_fifo_high_threshold);
1453 viafb_load_reg_num =
1454 fifo_high_threshold_select_reg.
1455 iga2_fifo_high_threshold_select_reg.reg_num;
1456 reg =
1457 fifo_high_threshold_select_reg.
1458 iga2_fifo_high_threshold_select_reg.reg;
1459 viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
1460
1461 /* Set Display Queue Expire Num */
1462 reg_value =
1463 IGA2_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA
1464 (iga2_display_queue_expire_num);
1465 viafb_load_reg_num =
1466 display_queue_expire_num_reg.
1467 iga2_display_queue_expire_num_reg.reg_num;
1468 reg =
1469 display_queue_expire_num_reg.
1470 iga2_display_queue_expire_num_reg.reg;
1471 viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
1472
1473 }
1474
1475}
1476
1477u32 viafb_get_clk_value(int clk)
1478{
1479 int i;
1480
1481 for (i = 0; i < NUM_TOTAL_PLL_TABLE; i++) {
1482 if (clk == pll_value[i].clk) {
1483 switch (viaparinfo->chip_info->gfx_chip_name) {
1484 case UNICHROME_CLE266:
1485 case UNICHROME_K400:
1486 return pll_value[i].cle266_pll;
1487
1488 case UNICHROME_K800:
1489 case UNICHROME_PM800:
1490 case UNICHROME_CN700:
1491 return pll_value[i].k800_pll;
1492
1493 case UNICHROME_CX700:
1494 case UNICHROME_K8M890:
1495 case UNICHROME_P4M890:
1496 case UNICHROME_P4M900:
1497 case UNICHROME_VX800:
1498 return pll_value[i].cx700_pll;
1499 }
1500 }
1501 }
1502
1503 DEBUG_MSG(KERN_INFO "Can't find match PLL value\n\n");
1504 return 0;
1505}
1506
1507/* Set VCLK*/
1508void viafb_set_vclock(u32 CLK, int set_iga)
1509{
1510 unsigned char RegTemp;
1511
1512 /* H.W. Reset : ON */
1513 viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
1514
1515 if ((set_iga == IGA1) || (set_iga == IGA1_IGA2)) {
1516 /* Change D,N FOR VCLK */
1517 switch (viaparinfo->chip_info->gfx_chip_name) {
1518 case UNICHROME_CLE266:
1519 case UNICHROME_K400:
1520 viafb_write_reg(SR46, VIASR, CLK / 0x100);
1521 viafb_write_reg(SR47, VIASR, CLK % 0x100);
1522 break;
1523
1524 case UNICHROME_K800:
1525 case UNICHROME_PM800:
1526 case UNICHROME_CN700:
1527 case UNICHROME_CX700:
1528 case UNICHROME_K8M890:
1529 case UNICHROME_P4M890:
1530 case UNICHROME_P4M900:
1531 case UNICHROME_VX800:
1532 viafb_write_reg(SR44, VIASR, CLK / 0x10000);
1533 DEBUG_MSG(KERN_INFO "\nSR44=%x", CLK / 0x10000);
1534 viafb_write_reg(SR45, VIASR, (CLK & 0xFFFF) / 0x100);
1535 DEBUG_MSG(KERN_INFO "\nSR45=%x",
1536 (CLK & 0xFFFF) / 0x100);
1537 viafb_write_reg(SR46, VIASR, CLK % 0x100);
1538 DEBUG_MSG(KERN_INFO "\nSR46=%x", CLK % 0x100);
1539 break;
1540 }
1541 }
1542
1543 if ((set_iga == IGA2) || (set_iga == IGA1_IGA2)) {
1544 /* Change D,N FOR LCK */
1545 switch (viaparinfo->chip_info->gfx_chip_name) {
1546 case UNICHROME_CLE266:
1547 case UNICHROME_K400:
1548 viafb_write_reg(SR44, VIASR, CLK / 0x100);
1549 viafb_write_reg(SR45, VIASR, CLK % 0x100);
1550 break;
1551
1552 case UNICHROME_K800:
1553 case UNICHROME_PM800:
1554 case UNICHROME_CN700:
1555 case UNICHROME_CX700:
1556 case UNICHROME_K8M890:
1557 case UNICHROME_P4M890:
1558 case UNICHROME_P4M900:
1559 case UNICHROME_VX800:
1560 viafb_write_reg(SR4A, VIASR, CLK / 0x10000);
1561 viafb_write_reg(SR4B, VIASR, (CLK & 0xFFFF) / 0x100);
1562 viafb_write_reg(SR4C, VIASR, CLK % 0x100);
1563 break;
1564 }
1565 }
1566
1567 /* H.W. Reset : OFF */
1568 viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
1569
1570 /* Reset PLL */
1571 if ((set_iga == IGA1) || (set_iga == IGA1_IGA2)) {
1572 viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1);
1573 viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1);
1574 }
1575
1576 if ((set_iga == IGA2) || (set_iga == IGA1_IGA2)) {
1577 viafb_write_reg_mask(SR40, VIASR, 0x01, BIT0);
1578 viafb_write_reg_mask(SR40, VIASR, 0x00, BIT0);
1579 }
1580
1581 /* Fire! */
1582 RegTemp = inb(VIARMisc);
1583 outb(RegTemp | (BIT2 + BIT3), VIAWMisc);
1584}
1585
1586void viafb_load_crtc_timing(struct display_timing device_timing,
1587 int set_iga)
1588{
1589 int i;
1590 int viafb_load_reg_num = 0;
1591 int reg_value = 0;
1592 struct io_register *reg = NULL;
1593
1594 viafb_unlock_crt();
1595
1596 for (i = 0; i < 12; i++) {
1597 if (set_iga == IGA1) {
1598 switch (i) {
1599 case H_TOTAL_INDEX:
1600 reg_value =
1601 IGA1_HOR_TOTAL_FORMULA(device_timing.
1602 hor_total);
1603 viafb_load_reg_num =
1604 iga1_crtc_reg.hor_total.reg_num;
1605 reg = iga1_crtc_reg.hor_total.reg;
1606 break;
1607 case H_ADDR_INDEX:
1608 reg_value =
1609 IGA1_HOR_ADDR_FORMULA(device_timing.
1610 hor_addr);
1611 viafb_load_reg_num =
1612 iga1_crtc_reg.hor_addr.reg_num;
1613 reg = iga1_crtc_reg.hor_addr.reg;
1614 break;
1615 case H_BLANK_START_INDEX:
1616 reg_value =
1617 IGA1_HOR_BLANK_START_FORMULA
1618 (device_timing.hor_blank_start);
1619 viafb_load_reg_num =
1620 iga1_crtc_reg.hor_blank_start.reg_num;
1621 reg = iga1_crtc_reg.hor_blank_start.reg;
1622 break;
1623 case H_BLANK_END_INDEX:
1624 reg_value =
1625 IGA1_HOR_BLANK_END_FORMULA
1626 (device_timing.hor_blank_start,
1627 device_timing.hor_blank_end);
1628 viafb_load_reg_num =
1629 iga1_crtc_reg.hor_blank_end.reg_num;
1630 reg = iga1_crtc_reg.hor_blank_end.reg;
1631 break;
1632 case H_SYNC_START_INDEX:
1633 reg_value =
1634 IGA1_HOR_SYNC_START_FORMULA
1635 (device_timing.hor_sync_start);
1636 viafb_load_reg_num =
1637 iga1_crtc_reg.hor_sync_start.reg_num;
1638 reg = iga1_crtc_reg.hor_sync_start.reg;
1639 break;
1640 case H_SYNC_END_INDEX:
1641 reg_value =
1642 IGA1_HOR_SYNC_END_FORMULA
1643 (device_timing.hor_sync_start,
1644 device_timing.hor_sync_end);
1645 viafb_load_reg_num =
1646 iga1_crtc_reg.hor_sync_end.reg_num;
1647 reg = iga1_crtc_reg.hor_sync_end.reg;
1648 break;
1649 case V_TOTAL_INDEX:
1650 reg_value =
1651 IGA1_VER_TOTAL_FORMULA(device_timing.
1652 ver_total);
1653 viafb_load_reg_num =
1654 iga1_crtc_reg.ver_total.reg_num;
1655 reg = iga1_crtc_reg.ver_total.reg;
1656 break;
1657 case V_ADDR_INDEX:
1658 reg_value =
1659 IGA1_VER_ADDR_FORMULA(device_timing.
1660 ver_addr);
1661 viafb_load_reg_num =
1662 iga1_crtc_reg.ver_addr.reg_num;
1663 reg = iga1_crtc_reg.ver_addr.reg;
1664 break;
1665 case V_BLANK_START_INDEX:
1666 reg_value =
1667 IGA1_VER_BLANK_START_FORMULA
1668 (device_timing.ver_blank_start);
1669 viafb_load_reg_num =
1670 iga1_crtc_reg.ver_blank_start.reg_num;
1671 reg = iga1_crtc_reg.ver_blank_start.reg;
1672 break;
1673 case V_BLANK_END_INDEX:
1674 reg_value =
1675 IGA1_VER_BLANK_END_FORMULA
1676 (device_timing.ver_blank_start,
1677 device_timing.ver_blank_end);
1678 viafb_load_reg_num =
1679 iga1_crtc_reg.ver_blank_end.reg_num;
1680 reg = iga1_crtc_reg.ver_blank_end.reg;
1681 break;
1682 case V_SYNC_START_INDEX:
1683 reg_value =
1684 IGA1_VER_SYNC_START_FORMULA
1685 (device_timing.ver_sync_start);
1686 viafb_load_reg_num =
1687 iga1_crtc_reg.ver_sync_start.reg_num;
1688 reg = iga1_crtc_reg.ver_sync_start.reg;
1689 break;
1690 case V_SYNC_END_INDEX:
1691 reg_value =
1692 IGA1_VER_SYNC_END_FORMULA
1693 (device_timing.ver_sync_start,
1694 device_timing.ver_sync_end);
1695 viafb_load_reg_num =
1696 iga1_crtc_reg.ver_sync_end.reg_num;
1697 reg = iga1_crtc_reg.ver_sync_end.reg;
1698 break;
1699
1700 }
1701 }
1702
1703 if (set_iga == IGA2) {
1704 switch (i) {
1705 case H_TOTAL_INDEX:
1706 reg_value =
1707 IGA2_HOR_TOTAL_FORMULA(device_timing.
1708 hor_total);
1709 viafb_load_reg_num =
1710 iga2_crtc_reg.hor_total.reg_num;
1711 reg = iga2_crtc_reg.hor_total.reg;
1712 break;
1713 case H_ADDR_INDEX:
1714 reg_value =
1715 IGA2_HOR_ADDR_FORMULA(device_timing.
1716 hor_addr);
1717 viafb_load_reg_num =
1718 iga2_crtc_reg.hor_addr.reg_num;
1719 reg = iga2_crtc_reg.hor_addr.reg;
1720 break;
1721 case H_BLANK_START_INDEX:
1722 reg_value =
1723 IGA2_HOR_BLANK_START_FORMULA
1724 (device_timing.hor_blank_start);
1725 viafb_load_reg_num =
1726 iga2_crtc_reg.hor_blank_start.reg_num;
1727 reg = iga2_crtc_reg.hor_blank_start.reg;
1728 break;
1729 case H_BLANK_END_INDEX:
1730 reg_value =
1731 IGA2_HOR_BLANK_END_FORMULA
1732 (device_timing.hor_blank_start,
1733 device_timing.hor_blank_end);
1734 viafb_load_reg_num =
1735 iga2_crtc_reg.hor_blank_end.reg_num;
1736 reg = iga2_crtc_reg.hor_blank_end.reg;
1737 break;
1738 case H_SYNC_START_INDEX:
1739 reg_value =
1740 IGA2_HOR_SYNC_START_FORMULA
1741 (device_timing.hor_sync_start);
1742 if (UNICHROME_CN700 <=
1743 viaparinfo->chip_info->gfx_chip_name)
1744 viafb_load_reg_num =
1745 iga2_crtc_reg.hor_sync_start.
1746 reg_num;
1747 else
1748 viafb_load_reg_num = 3;
1749 reg = iga2_crtc_reg.hor_sync_start.reg;
1750 break;
1751 case H_SYNC_END_INDEX:
1752 reg_value =
1753 IGA2_HOR_SYNC_END_FORMULA
1754 (device_timing.hor_sync_start,
1755 device_timing.hor_sync_end);
1756 viafb_load_reg_num =
1757 iga2_crtc_reg.hor_sync_end.reg_num;
1758 reg = iga2_crtc_reg.hor_sync_end.reg;
1759 break;
1760 case V_TOTAL_INDEX:
1761 reg_value =
1762 IGA2_VER_TOTAL_FORMULA(device_timing.
1763 ver_total);
1764 viafb_load_reg_num =
1765 iga2_crtc_reg.ver_total.reg_num;
1766 reg = iga2_crtc_reg.ver_total.reg;
1767 break;
1768 case V_ADDR_INDEX:
1769 reg_value =
1770 IGA2_VER_ADDR_FORMULA(device_timing.
1771 ver_addr);
1772 viafb_load_reg_num =
1773 iga2_crtc_reg.ver_addr.reg_num;
1774 reg = iga2_crtc_reg.ver_addr.reg;
1775 break;
1776 case V_BLANK_START_INDEX:
1777 reg_value =
1778 IGA2_VER_BLANK_START_FORMULA
1779 (device_timing.ver_blank_start);
1780 viafb_load_reg_num =
1781 iga2_crtc_reg.ver_blank_start.reg_num;
1782 reg = iga2_crtc_reg.ver_blank_start.reg;
1783 break;
1784 case V_BLANK_END_INDEX:
1785 reg_value =
1786 IGA2_VER_BLANK_END_FORMULA
1787 (device_timing.ver_blank_start,
1788 device_timing.ver_blank_end);
1789 viafb_load_reg_num =
1790 iga2_crtc_reg.ver_blank_end.reg_num;
1791 reg = iga2_crtc_reg.ver_blank_end.reg;
1792 break;
1793 case V_SYNC_START_INDEX:
1794 reg_value =
1795 IGA2_VER_SYNC_START_FORMULA
1796 (device_timing.ver_sync_start);
1797 viafb_load_reg_num =
1798 iga2_crtc_reg.ver_sync_start.reg_num;
1799 reg = iga2_crtc_reg.ver_sync_start.reg;
1800 break;
1801 case V_SYNC_END_INDEX:
1802 reg_value =
1803 IGA2_VER_SYNC_END_FORMULA
1804 (device_timing.ver_sync_start,
1805 device_timing.ver_sync_end);
1806 viafb_load_reg_num =
1807 iga2_crtc_reg.ver_sync_end.reg_num;
1808 reg = iga2_crtc_reg.ver_sync_end.reg;
1809 break;
1810
1811 }
1812 }
1813 viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
1814 }
1815
1816 viafb_lock_crt();
1817}
1818
1819void viafb_set_color_depth(int bpp_byte, int set_iga)
1820{
1821 if (set_iga == IGA1) {
1822 switch (bpp_byte) {
1823 case MODE_8BPP:
1824 viafb_write_reg_mask(SR15, VIASR, 0x22, 0x7E);
1825 break;
1826 case MODE_16BPP:
1827 viafb_write_reg_mask(SR15, VIASR, 0xB6, 0xFE);
1828 break;
1829 case MODE_32BPP:
1830 viafb_write_reg_mask(SR15, VIASR, 0xAE, 0xFE);
1831 break;
1832 }
1833 } else {
1834 switch (bpp_byte) {
1835 case MODE_8BPP:
1836 viafb_write_reg_mask(CR67, VIACR, 0x00, BIT6 + BIT7);
1837 break;
1838 case MODE_16BPP:
1839 viafb_write_reg_mask(CR67, VIACR, 0x40, BIT6 + BIT7);
1840 break;
1841 case MODE_32BPP:
1842 viafb_write_reg_mask(CR67, VIACR, 0xC0, BIT6 + BIT7);
1843 break;
1844 }
1845 }
1846}
1847
1848void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
1849 int mode_index, int bpp_byte, int set_iga)
1850{
1851 struct VideoModeTable *video_mode;
1852 struct display_timing crt_reg;
1853 int i;
1854 int index = 0;
1855 int h_addr, v_addr;
1856 u32 pll_D_N;
1857
1858 video_mode = &CLE266Modes[search_mode_setting(mode_index)];
1859
1860 for (i = 0; i < video_mode->mode_array; i++) {
1861 index = i;
1862
1863 if (crt_table[i].refresh_rate == viaparinfo->
1864 crt_setting_info->refresh_rate)
1865 break;
1866 }
1867
1868 crt_reg = crt_table[index].crtc;
1869
1870 /* Mode 640x480 has border, but LCD/DFP didn't have border. */
1871 /* So we would delete border. */
1872 if ((viafb_LCD_ON | viafb_DVI_ON) && (mode_index == VIA_RES_640X480)
1873 && (viaparinfo->crt_setting_info->refresh_rate == 60)) {
1874 /* The border is 8 pixels. */
1875 crt_reg.hor_blank_start = crt_reg.hor_blank_start - 8;
1876
1877 /* Blanking time should add left and right borders. */
1878 crt_reg.hor_blank_end = crt_reg.hor_blank_end + 16;
1879 }
1880
1881 h_addr = crt_reg.hor_addr;
1882 v_addr = crt_reg.ver_addr;
1883
1884 /* update polarity for CRT timing */
1885 if (crt_table[index].h_sync_polarity == NEGATIVE) {
1886 if (crt_table[index].v_sync_polarity == NEGATIVE)
1887 outb((inb(VIARMisc) & (~(BIT6 + BIT7))) |
1888 (BIT6 + BIT7), VIAWMisc);
1889 else
1890 outb((inb(VIARMisc) & (~(BIT6 + BIT7))) | (BIT6),
1891 VIAWMisc);
1892 } else {
1893 if (crt_table[index].v_sync_polarity == NEGATIVE)
1894 outb((inb(VIARMisc) & (~(BIT6 + BIT7))) | (BIT7),
1895 VIAWMisc);
1896 else
1897 outb((inb(VIARMisc) & (~(BIT6 + BIT7))), VIAWMisc);
1898 }
1899
1900 if (set_iga == IGA1) {
1901 viafb_unlock_crt();
1902 viafb_write_reg(CR09, VIACR, 0x00); /*initial CR09=0 */
1903 viafb_write_reg_mask(CR11, VIACR, 0x00, BIT4 + BIT5 + BIT6);
1904 viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
1905 }
1906
1907 switch (set_iga) {
1908 case IGA1:
1909 viafb_load_crtc_timing(crt_reg, IGA1);
1910 break;
1911 case IGA2:
1912 viafb_load_crtc_timing(crt_reg, IGA2);
1913 break;
1914 }
1915
1916 load_fix_bit_crtc_reg();
1917 viafb_lock_crt();
1918 viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
1919 viafb_load_offset_reg(h_addr, bpp_byte, set_iga);
1920 viafb_load_fetch_count_reg(h_addr, bpp_byte, set_iga);
1921
1922 /* load FIFO */
1923 if ((viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266)
1924 && (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400))
1925 viafb_load_FIFO_reg(set_iga, h_addr, v_addr);
1926
1927 /* load SR Register About Memory and Color part */
1928 viafb_set_color_depth(bpp_byte, set_iga);
1929
1930 pll_D_N = viafb_get_clk_value(crt_table[index].clk);
1931 DEBUG_MSG(KERN_INFO "PLL=%x", pll_D_N);
1932 viafb_set_vclock(pll_D_N, set_iga);
1933
1934}
1935
1936void viafb_init_chip_info(void)
1937{
1938 init_gfx_chip_info();
1939 init_tmds_chip_info();
1940 init_lvds_chip_info();
1941
1942 viaparinfo->crt_setting_info->iga_path = IGA1;
1943 viaparinfo->crt_setting_info->refresh_rate = viafb_refresh;
1944
1945 /*Set IGA path for each device */
1946 viafb_set_iga_path();
1947
1948 viaparinfo->lvds_setting_info->display_method = viafb_lcd_dsp_method;
1949 viaparinfo->lvds_setting_info->get_lcd_size_method =
1950 GET_LCD_SIZE_BY_USER_SETTING;
1951 viaparinfo->lvds_setting_info->lcd_mode = viafb_lcd_mode;
1952 viaparinfo->lvds_setting_info2->display_method =
1953 viaparinfo->lvds_setting_info->display_method;
1954 viaparinfo->lvds_setting_info2->lcd_mode =
1955 viaparinfo->lvds_setting_info->lcd_mode;
1956}
1957
1958void viafb_update_device_setting(int hres, int vres,
1959 int bpp, int vmode_refresh, int flag)
1960{
1961 if (flag == 0) {
1962 viaparinfo->crt_setting_info->h_active = hres;
1963 viaparinfo->crt_setting_info->v_active = vres;
1964 viaparinfo->crt_setting_info->bpp = bpp;
1965 viaparinfo->crt_setting_info->refresh_rate =
1966 vmode_refresh;
1967
1968 viaparinfo->tmds_setting_info->h_active = hres;
1969 viaparinfo->tmds_setting_info->v_active = vres;
1970 viaparinfo->tmds_setting_info->bpp = bpp;
1971 viaparinfo->tmds_setting_info->refresh_rate =
1972 vmode_refresh;
1973
1974 viaparinfo->lvds_setting_info->h_active = hres;
1975 viaparinfo->lvds_setting_info->v_active = vres;
1976 viaparinfo->lvds_setting_info->bpp = bpp;
1977 viaparinfo->lvds_setting_info->refresh_rate =
1978 vmode_refresh;
1979 viaparinfo->lvds_setting_info2->h_active = hres;
1980 viaparinfo->lvds_setting_info2->v_active = vres;
1981 viaparinfo->lvds_setting_info2->bpp = bpp;
1982 viaparinfo->lvds_setting_info2->refresh_rate =
1983 vmode_refresh;
1984 } else {
1985
1986 if (viaparinfo->tmds_setting_info->iga_path == IGA2) {
1987 viaparinfo->tmds_setting_info->h_active = hres;
1988 viaparinfo->tmds_setting_info->v_active = vres;
1989 viaparinfo->tmds_setting_info->bpp = bpp;
1990 viaparinfo->tmds_setting_info->refresh_rate =
1991 vmode_refresh;
1992 }
1993
1994 if (viaparinfo->lvds_setting_info->iga_path == IGA2) {
1995 viaparinfo->lvds_setting_info->h_active = hres;
1996 viaparinfo->lvds_setting_info->v_active = vres;
1997 viaparinfo->lvds_setting_info->bpp = bpp;
1998 viaparinfo->lvds_setting_info->refresh_rate =
1999 vmode_refresh;
2000 }
2001 if (IGA2 == viaparinfo->lvds_setting_info2->iga_path) {
2002 viaparinfo->lvds_setting_info2->h_active = hres;
2003 viaparinfo->lvds_setting_info2->v_active = vres;
2004 viaparinfo->lvds_setting_info2->bpp = bpp;
2005 viaparinfo->lvds_setting_info2->refresh_rate =
2006 vmode_refresh;
2007 }
2008 }
2009}
2010
2011static void init_gfx_chip_info(void)
2012{
2013 struct pci_dev *pdev = NULL;
2014 u32 i;
2015 u8 tmp;
2016
2017 /* Indentify GFX Chip Name */
2018 for (i = 0; pciidlist[i].vendor != 0; i++) {
2019 pdev = pci_get_device(pciidlist[i].vendor,
2020 pciidlist[i].device, 0);
2021 if (pdev)
2022 break;
2023 }
2024
2025 if (!pciidlist[i].vendor)
2026 return ;
2027
2028 viaparinfo->chip_info->gfx_chip_name = pciidlist[i].chip_index;
2029
2030 /* Check revision of CLE266 Chip */
2031 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
2032 /* CR4F only define in CLE266.CX chip */
2033 tmp = viafb_read_reg(VIACR, CR4F);
2034 viafb_write_reg(CR4F, VIACR, 0x55);
2035 if (viafb_read_reg(VIACR, CR4F) != 0x55)
2036 viaparinfo->chip_info->gfx_chip_revision =
2037 CLE266_REVISION_AX;
2038 else
2039 viaparinfo->chip_info->gfx_chip_revision =
2040 CLE266_REVISION_CX;
2041 /* restore orignal CR4F value */
2042 viafb_write_reg(CR4F, VIACR, tmp);
2043 }
2044
2045 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
2046 tmp = viafb_read_reg(VIASR, SR43);
2047 DEBUG_MSG(KERN_INFO "SR43:%X\n", tmp);
2048 if (tmp & 0x02) {
2049 viaparinfo->chip_info->gfx_chip_revision =
2050 CX700_REVISION_700M2;
2051 } else if (tmp & 0x40) {
2052 viaparinfo->chip_info->gfx_chip_revision =
2053 CX700_REVISION_700M;
2054 } else {
2055 viaparinfo->chip_info->gfx_chip_revision =
2056 CX700_REVISION_700;
2057 }
2058 }
2059
2060 pci_dev_put(pdev);
2061}
2062
2063static void init_tmds_chip_info(void)
2064{
2065 viafb_tmds_trasmitter_identify();
2066
2067 if (INTERFACE_NONE == viaparinfo->chip_info->tmds_chip_info.
2068 output_interface) {
2069 switch (viaparinfo->chip_info->gfx_chip_name) {
2070 case UNICHROME_CX700:
2071 {
2072 /* we should check support by hardware layout.*/
2073 if ((viafb_display_hardware_layout ==
2074 HW_LAYOUT_DVI_ONLY)
2075 || (viafb_display_hardware_layout ==
2076 HW_LAYOUT_LCD_DVI)) {
2077 viaparinfo->chip_info->tmds_chip_info.
2078 output_interface = INTERFACE_TMDS;
2079 } else {
2080 viaparinfo->chip_info->tmds_chip_info.
2081 output_interface =
2082 INTERFACE_NONE;
2083 }
2084 break;
2085 }
2086 case UNICHROME_K8M890:
2087 case UNICHROME_P4M900:
2088 case UNICHROME_P4M890:
2089 /* TMDS on PCIE, we set DFPLOW as default. */
2090 viaparinfo->chip_info->tmds_chip_info.output_interface =
2091 INTERFACE_DFP_LOW;
2092 break;
2093 default:
2094 {
2095 /* set DVP1 default for DVI */
2096 viaparinfo->chip_info->tmds_chip_info
2097 .output_interface = INTERFACE_DVP1;
2098 }
2099 }
2100 }
2101
2102 DEBUG_MSG(KERN_INFO "TMDS Chip = %d\n",
2103 viaparinfo->chip_info->tmds_chip_info.tmds_chip_name);
2104 viaparinfo->tmds_setting_info->get_dvi_size_method =
2105 GET_DVI_SIZE_BY_VGA_BIOS;
2106 viafb_init_dvi_size();
2107}
2108
2109static void init_lvds_chip_info(void)
2110{
2111 if (viafb_lcd_panel_id > LCD_PANEL_ID_MAXIMUM)
2112 viaparinfo->lvds_setting_info->get_lcd_size_method =
2113 GET_LCD_SIZE_BY_VGA_BIOS;
2114 else
2115 viaparinfo->lvds_setting_info->get_lcd_size_method =
2116 GET_LCD_SIZE_BY_USER_SETTING;
2117
2118 viafb_lvds_trasmitter_identify();
2119 viafb_init_lcd_size();
2120 viafb_init_lvds_output_interface(&viaparinfo->chip_info->lvds_chip_info,
2121 viaparinfo->lvds_setting_info);
2122 if (viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) {
2123 viafb_init_lvds_output_interface(&viaparinfo->chip_info->
2124 lvds_chip_info2, viaparinfo->lvds_setting_info2);
2125 }
2126 /*If CX700,two singel LCD, we need to reassign
2127 LCD interface to different LVDS port */
2128 if ((UNICHROME_CX700 == viaparinfo->chip_info->gfx_chip_name)
2129 && (HW_LAYOUT_LCD1_LCD2 == viafb_display_hardware_layout)) {
2130 if ((INTEGRATED_LVDS == viaparinfo->chip_info->lvds_chip_info.
2131 lvds_chip_name) && (INTEGRATED_LVDS ==
2132 viaparinfo->chip_info->
2133 lvds_chip_info2.lvds_chip_name)) {
2134 viaparinfo->chip_info->lvds_chip_info.output_interface =
2135 INTERFACE_LVDS0;
2136 viaparinfo->chip_info->lvds_chip_info2.
2137 output_interface =
2138 INTERFACE_LVDS1;
2139 }
2140 }
2141
2142 DEBUG_MSG(KERN_INFO "LVDS Chip = %d\n",
2143 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name);
2144 DEBUG_MSG(KERN_INFO "LVDS1 output_interface = %d\n",
2145 viaparinfo->chip_info->lvds_chip_info.output_interface);
2146 DEBUG_MSG(KERN_INFO "LVDS2 output_interface = %d\n",
2147 viaparinfo->chip_info->lvds_chip_info.output_interface);
2148}
2149
2150void viafb_init_dac(int set_iga)
2151{
2152 int i;
2153 u8 tmp;
2154
2155 if (set_iga == IGA1) {
2156 /* access Primary Display's LUT */
2157 viafb_write_reg_mask(SR1A, VIASR, 0x00, BIT0);
2158 /* turn off LCK */
2159 viafb_write_reg_mask(SR1B, VIASR, 0x00, BIT7 + BIT6);
2160 for (i = 0; i < 256; i++) {
2161 write_dac_reg(i, palLUT_table[i].red,
2162 palLUT_table[i].green,
2163 palLUT_table[i].blue);
2164 }
2165 /* turn on LCK */
2166 viafb_write_reg_mask(SR1B, VIASR, 0xC0, BIT7 + BIT6);
2167 } else {
2168 tmp = viafb_read_reg(VIACR, CR6A);
2169 /* access Secondary Display's LUT */
2170 viafb_write_reg_mask(CR6A, VIACR, 0x40, BIT6);
2171 viafb_write_reg_mask(SR1A, VIASR, 0x01, BIT0);
2172 for (i = 0; i < 256; i++) {
2173 write_dac_reg(i, palLUT_table[i].red,
2174 palLUT_table[i].green,
2175 palLUT_table[i].blue);
2176 }
2177 /* set IGA1 DAC for default */
2178 viafb_write_reg_mask(SR1A, VIASR, 0x00, BIT0);
2179 viafb_write_reg(CR6A, VIACR, tmp);
2180 }
2181}
2182
2183static void device_screen_off(void)
2184{
2185 /* turn off CRT screen (IGA1) */
2186 viafb_write_reg_mask(SR01, VIASR, 0x20, BIT5);
2187}
2188
2189static void device_screen_on(void)
2190{
2191 /* turn on CRT screen (IGA1) */
2192 viafb_write_reg_mask(SR01, VIASR, 0x00, BIT5);
2193}
2194
2195static void set_display_channel(void)
2196{
2197 /*If viafb_LCD2_ON, on cx700, internal lvds's information
2198 is keeped on lvds_setting_info2 */
2199 if (viafb_LCD2_ON &&
2200 viaparinfo->lvds_setting_info2->device_lcd_dualedge) {
2201 /* For dual channel LCD: */
2202 /* Set to Dual LVDS channel. */
2203 viafb_write_reg_mask(CRD2, VIACR, 0x20, BIT4 + BIT5);
2204 } else if (viafb_LCD_ON && viafb_DVI_ON) {
2205 /* For LCD+DFP: */
2206 /* Set to LVDS1 + TMDS channel. */
2207 viafb_write_reg_mask(CRD2, VIACR, 0x10, BIT4 + BIT5);
2208 } else if (viafb_DVI_ON) {
2209 /* Set to single TMDS channel. */
2210 viafb_write_reg_mask(CRD2, VIACR, 0x30, BIT4 + BIT5);
2211 } else if (viafb_LCD_ON) {
2212 if (viaparinfo->lvds_setting_info->device_lcd_dualedge) {
2213 /* For dual channel LCD: */
2214 /* Set to Dual LVDS channel. */
2215 viafb_write_reg_mask(CRD2, VIACR, 0x20, BIT4 + BIT5);
2216 } else {
2217 /* Set to LVDS0 + LVDS1 channel. */
2218 viafb_write_reg_mask(CRD2, VIACR, 0x00, BIT4 + BIT5);
2219 }
2220 }
2221}
2222
2223int viafb_setmode(int vmode_index, int hor_res, int ver_res, int video_bpp,
2224 int vmode_index1, int hor_res1, int ver_res1, int video_bpp1)
2225{
2226 int i, j;
2227 int port;
2228 u8 value, index, mask;
2229 struct VideoModeTable *vmode_tbl;
2230 struct crt_mode_table *crt_timing;
2231 struct VideoModeTable *vmode_tbl1 = NULL;
2232 struct crt_mode_table *crt_timing1 = NULL;
2233
2234 DEBUG_MSG(KERN_INFO "Set Mode!!\n");
2235 DEBUG_MSG(KERN_INFO
2236 "vmode_index=%d hor_res=%d ver_res=%d video_bpp=%d\n",
2237 vmode_index, hor_res, ver_res, video_bpp);
2238
2239 device_screen_off();
2240 vmode_tbl = &CLE266Modes[search_mode_setting(vmode_index)];
2241 crt_timing = vmode_tbl->crtc;
2242
2243 if (viafb_SAMM_ON == 1) {
2244 vmode_tbl1 = &CLE266Modes[search_mode_setting(vmode_index1)];
2245 crt_timing1 = vmode_tbl1->crtc;
2246 }
2247
2248 inb(VIAStatus);
2249 outb(0x00, VIAAR);
2250
2251 /* Write Common Setting for Video Mode */
2252 switch (viaparinfo->chip_info->gfx_chip_name) {
2253 case UNICHROME_CLE266:
2254 viafb_write_regx(CLE266_ModeXregs, NUM_TOTAL_CLE266_ModeXregs);
2255 break;
2256
2257 case UNICHROME_K400:
2258 viafb_write_regx(KM400_ModeXregs, NUM_TOTAL_KM400_ModeXregs);
2259 break;
2260
2261 case UNICHROME_K800:
2262 case UNICHROME_PM800:
2263 viafb_write_regx(CN400_ModeXregs, NUM_TOTAL_CN400_ModeXregs);
2264 break;
2265
2266 case UNICHROME_CN700:
2267 case UNICHROME_K8M890:
2268 case UNICHROME_P4M890:
2269 case UNICHROME_P4M900:
2270 viafb_write_regx(CN700_ModeXregs, NUM_TOTAL_CN700_ModeXregs);
2271 break;
2272
2273 case UNICHROME_CX700:
2274 viafb_write_regx(CX700_ModeXregs, NUM_TOTAL_CX700_ModeXregs);
2275
2276 case UNICHROME_VX800:
2277 viafb_write_regx(VX800_ModeXregs, NUM_TOTAL_VX800_ModeXregs);
2278
2279 break;
2280 }
2281
2282 device_off();
2283
2284 /* Fill VPIT Parameters */
2285 /* Write Misc Register */
2286 outb(VPIT.Misc, VIAWMisc);
2287
2288 /* Write Sequencer */
2289 for (i = 1; i <= StdSR; i++) {
2290 outb(i, VIASR);
2291 outb(VPIT.SR[i - 1], VIASR + 1);
2292 }
2293
2294 viafb_set_start_addr();
2295 viafb_set_iga_path();
2296
2297 /* Write CRTC */
2298 viafb_fill_crtc_timing(crt_timing, vmode_index, video_bpp / 8, IGA1);
2299
2300 /* Write Graphic Controller */
2301 for (i = 0; i < StdGR; i++) {
2302 outb(i, VIAGR);
2303 outb(VPIT.GR[i], VIAGR + 1);
2304 }
2305
2306 /* Write Attribute Controller */
2307 for (i = 0; i < StdAR; i++) {
2308 inb(VIAStatus);
2309 outb(i, VIAAR);
2310 outb(VPIT.AR[i], VIAAR);
2311 }
2312
2313 inb(VIAStatus);
2314 outb(0x20, VIAAR);
2315
2316 /* Update Patch Register */
2317
2318 if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
2319 || (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K400)) {
2320 for (i = 0; i < NUM_TOTAL_PATCH_MODE; i++) {
2321 if (res_patch_table[i].mode_index == vmode_index) {
2322 for (j = 0;
2323 j < res_patch_table[i].table_length; j++) {
2324 index =
2325 res_patch_table[i].
2326 io_reg_table[j].index;
2327 port =
2328 res_patch_table[i].
2329 io_reg_table[j].port;
2330 value =
2331 res_patch_table[i].
2332 io_reg_table[j].value;
2333 mask =
2334 res_patch_table[i].
2335 io_reg_table[j].mask;
2336 viafb_write_reg_mask(index, port, value,
2337 mask);
2338 }
2339 }
2340 }
2341 }
2342
2343 if (viafb_SAMM_ON == 1) {
2344 if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
2345 || (viaparinfo->chip_info->gfx_chip_name ==
2346 UNICHROME_K400)) {
2347 for (i = 0; i < NUM_TOTAL_PATCH_MODE; i++) {
2348 if (res_patch_table[i].mode_index ==
2349 vmode_index1) {
2350 for (j = 0;
2351 j <
2352 res_patch_table[i].
2353 table_length; j++) {
2354 index =
2355 res_patch_table[i].
2356 io_reg_table[j].index;
2357 port =
2358 res_patch_table[i].
2359 io_reg_table[j].port;
2360 value =
2361 res_patch_table[i].
2362 io_reg_table[j].value;
2363 mask =
2364 res_patch_table[i].
2365 io_reg_table[j].mask;
2366 viafb_write_reg_mask(index,
2367 port, value, mask);
2368 }
2369 }
2370 }
2371 }
2372 }
2373
2374 /* Update Refresh Rate Setting */
2375
2376 /* Clear On Screen */
2377
2378 /* CRT set mode */
2379 if (viafb_CRT_ON) {
2380 if (viafb_SAMM_ON && (viaparinfo->crt_setting_info->iga_path ==
2381 IGA2)) {
2382 viafb_fill_crtc_timing(crt_timing1, vmode_index1,
2383 video_bpp1 / 8,
2384 viaparinfo->crt_setting_info->iga_path);
2385 } else {
2386 viafb_fill_crtc_timing(crt_timing, vmode_index,
2387 video_bpp / 8,
2388 viaparinfo->crt_setting_info->iga_path);
2389 }
2390
2391 set_crt_output_path(viaparinfo->crt_setting_info->iga_path);
2392
2393 /* Patch if set_hres is not 8 alignment (1366) to viafb_setmode
2394 to 8 alignment (1368),there is several pixels (2 pixels)
2395 on right side of screen. */
2396 if (hor_res % 8) {
2397 viafb_unlock_crt();
2398 viafb_write_reg(CR02, VIACR,
2399 viafb_read_reg(VIACR, CR02) - 1);
2400 viafb_lock_crt();
2401 }
2402 }
2403
2404 if (viafb_DVI_ON) {
2405 if (viafb_SAMM_ON &&
2406 (viaparinfo->tmds_setting_info->iga_path == IGA2)) {
2407 viafb_dvi_set_mode(viafb_get_mode_index
2408 (viaparinfo->tmds_setting_info->h_active,
2409 viaparinfo->tmds_setting_info->
2410 v_active, 1),
2411 video_bpp1, viaparinfo->
2412 tmds_setting_info->iga_path);
2413 } else {
2414 viafb_dvi_set_mode(viafb_get_mode_index
2415 (viaparinfo->tmds_setting_info->h_active,
2416 viaparinfo->
2417 tmds_setting_info->v_active, 0),
2418 video_bpp, viaparinfo->
2419 tmds_setting_info->iga_path);
2420 }
2421 }
2422
2423 if (viafb_LCD_ON) {
2424 if (viafb_SAMM_ON &&
2425 (viaparinfo->lvds_setting_info->iga_path == IGA2)) {
2426 viaparinfo->lvds_setting_info->bpp = video_bpp1;
2427 viafb_lcd_set_mode(crt_timing1, viaparinfo->
2428 lvds_setting_info,
2429 &viaparinfo->chip_info->lvds_chip_info);
2430 } else {
2431 /* IGA1 doesn't have LCD scaling, so set it center. */
2432 if (viaparinfo->lvds_setting_info->iga_path == IGA1) {
2433 viaparinfo->lvds_setting_info->display_method =
2434 LCD_CENTERING;
2435 }
2436 viaparinfo->lvds_setting_info->bpp = video_bpp;
2437 viafb_lcd_set_mode(crt_timing, viaparinfo->
2438 lvds_setting_info,
2439 &viaparinfo->chip_info->lvds_chip_info);
2440 }
2441 }
2442 if (viafb_LCD2_ON) {
2443 if (viafb_SAMM_ON &&
2444 (viaparinfo->lvds_setting_info2->iga_path == IGA2)) {
2445 viaparinfo->lvds_setting_info2->bpp = video_bpp1;
2446 viafb_lcd_set_mode(crt_timing1, viaparinfo->
2447 lvds_setting_info2,
2448 &viaparinfo->chip_info->lvds_chip_info2);
2449 } else {
2450 /* IGA1 doesn't have LCD scaling, so set it center. */
2451 if (viaparinfo->lvds_setting_info2->iga_path == IGA1) {
2452 viaparinfo->lvds_setting_info2->display_method =
2453 LCD_CENTERING;
2454 }
2455 viaparinfo->lvds_setting_info2->bpp = video_bpp;
2456 viafb_lcd_set_mode(crt_timing, viaparinfo->
2457 lvds_setting_info2,
2458 &viaparinfo->chip_info->lvds_chip_info2);
2459 }
2460 }
2461
2462 if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700)
2463 && (viafb_LCD_ON || viafb_DVI_ON))
2464 set_display_channel();
2465
2466 /* If set mode normally, save resolution information for hot-plug . */
2467 if (!viafb_hotplug) {
2468 viafb_hotplug_Xres = hor_res;
2469 viafb_hotplug_Yres = ver_res;
2470 viafb_hotplug_bpp = video_bpp;
2471 viafb_hotplug_refresh = viafb_refresh;
2472
2473 if (viafb_DVI_ON)
2474 viafb_DeviceStatus = DVI_Device;
2475 else
2476 viafb_DeviceStatus = CRT_Device;
2477 }
2478 device_on();
2479
2480 if (viafb_SAMM_ON == 1)
2481 viafb_write_reg_mask(CR6A, VIACR, 0xC0, BIT6 + BIT7);
2482
2483 device_screen_on();
2484 return 1;
2485}
2486
2487int viafb_get_pixclock(int hres, int vres, int vmode_refresh)
2488{
2489 int i;
2490
2491 for (i = 0; i < NUM_TOTAL_RES_MAP_REFRESH; i++) {
2492 if ((hres == res_map_refresh_tbl[i].hres)
2493 && (vres == res_map_refresh_tbl[i].vres)
2494 && (vmode_refresh == res_map_refresh_tbl[i].vmode_refresh))
2495 return res_map_refresh_tbl[i].pixclock;
2496 }
2497 return RES_640X480_60HZ_PIXCLOCK;
2498
2499}
2500
2501int viafb_get_refresh(int hres, int vres, u32 long_refresh)
2502{
2503#define REFRESH_TOLERANCE 3
2504 int i, nearest = -1, diff = REFRESH_TOLERANCE;
2505 for (i = 0; i < NUM_TOTAL_RES_MAP_REFRESH; i++) {
2506 if ((hres == res_map_refresh_tbl[i].hres)
2507 && (vres == res_map_refresh_tbl[i].vres)
2508 && (diff > (abs(long_refresh -
2509 res_map_refresh_tbl[i].vmode_refresh)))) {
2510 diff = abs(long_refresh - res_map_refresh_tbl[i].
2511 vmode_refresh);
2512 nearest = i;
2513 }
2514 }
2515#undef REFRESH_TOLERANCE
2516 if (nearest > 0)
2517 return res_map_refresh_tbl[nearest].vmode_refresh;
2518 return 60;
2519}
2520
2521static void device_off(void)
2522{
2523 viafb_crt_disable();
2524 viafb_dvi_disable();
2525 viafb_lcd_disable();
2526}
2527
2528static void device_on(void)
2529{
2530 if (viafb_CRT_ON == 1)
2531 viafb_crt_enable();
2532 if (viafb_DVI_ON == 1)
2533 viafb_dvi_enable();
2534 if (viafb_LCD_ON == 1)
2535 viafb_lcd_enable();
2536}
2537
2538void viafb_crt_disable(void)
2539{
2540 viafb_write_reg_mask(CR36, VIACR, BIT5 + BIT4, BIT5 + BIT4);
2541}
2542
2543void viafb_crt_enable(void)
2544{
2545 viafb_write_reg_mask(CR36, VIACR, 0x0, BIT5 + BIT4);
2546}
2547
2548void viafb_get_mmio_info(unsigned long *mmio_base,
2549 unsigned long *mmio_len)
2550{
2551 struct pci_dev *pdev = NULL;
2552 u32 vendor, device;
2553 u32 i;
2554
2555 for (i = 0; pciidlist[i].vendor != 0; i++)
2556 if (viaparinfo->chip_info->gfx_chip_name ==
2557 pciidlist[i].chip_index)
2558 break;
2559
2560 if (!pciidlist[i].vendor)
2561 return ;
2562
2563 vendor = pciidlist[i].vendor;
2564 device = pciidlist[i].device;
2565
2566 pdev = pci_get_device(vendor, device, NULL);
2567
2568 if (!pdev) {
2569 *mmio_base = 0;
2570 *mmio_len = 0;
2571 return ;
2572 }
2573
2574 *mmio_base = pci_resource_start(pdev, 1);
2575 *mmio_len = pci_resource_len(pdev, 1);
2576
2577 pci_dev_put(pdev);
2578}
2579
2580static void enable_second_display_channel(void)
2581{
2582 /* to enable second display channel. */
2583 viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT6);
2584 viafb_write_reg_mask(CR6A, VIACR, BIT7, BIT7);
2585 viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6);
2586}
2587
2588static void disable_second_display_channel(void)
2589{
2590 /* to disable second display channel. */
2591 viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT6);
2592 viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT7);
2593 viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6);
2594}
2595
2596void viafb_get_fb_info(unsigned int *fb_base, unsigned int *fb_len)
2597{
2598 struct pci_dev *pdev = NULL;
2599 u32 vendor, device;
2600 u32 i;
2601
2602 for (i = 0; pciidlist[i].vendor != 0; i++)
2603 if (viaparinfo->chip_info->gfx_chip_name ==
2604 pciidlist[i].chip_index)
2605 break;
2606
2607 if (!pciidlist[i].vendor)
2608 return ;
2609
2610 vendor = pciidlist[i].vendor;
2611 device = pciidlist[i].device;
2612
2613 pdev = pci_get_device(vendor, device, NULL);
2614
2615 if (!pdev) {
2616 *fb_base = viafb_read_reg(VIASR, SR30) << 24;
2617 *fb_len = viafb_get_memsize();
2618 DEBUG_MSG(KERN_INFO "Get FB info from SR30!\n");
2619 DEBUG_MSG(KERN_INFO "fb_base = %08x\n", *fb_base);
2620 DEBUG_MSG(KERN_INFO "fb_len = %08x\n", *fb_len);
2621 return ;
2622 }
2623
2624 *fb_base = (unsigned int)pci_resource_start(pdev, 0);
2625 *fb_len = get_fb_size_from_pci();
2626 DEBUG_MSG(KERN_INFO "Get FB info from PCI system!\n");
2627 DEBUG_MSG(KERN_INFO "fb_base = %08x\n", *fb_base);
2628 DEBUG_MSG(KERN_INFO "fb_len = %08x\n", *fb_len);
2629
2630 pci_dev_put(pdev);
2631}
2632
2633static int get_fb_size_from_pci(void)
2634{
2635 unsigned long configid, deviceid, FBSize = 0;
2636 int VideoMemSize;
2637 int DeviceFound = false;
2638
2639 for (configid = 0x80000000; configid < 0x80010800; configid += 0x100) {
2640 outl(configid, (unsigned long)0xCF8);
2641 deviceid = (inl((unsigned long)0xCFC) >> 16) & 0xffff;
2642
2643 switch (deviceid) {
2644 case CLE266:
2645 case KM400:
2646 outl(configid + 0xE0, (unsigned long)0xCF8);
2647 FBSize = inl((unsigned long)0xCFC);
2648 DeviceFound = true; /* Found device id */
2649 break;
2650
2651 case CN400_FUNCTION3:
2652 case CN700_FUNCTION3:
2653 case CX700_FUNCTION3:
2654 case KM800_FUNCTION3:
2655 case KM890_FUNCTION3:
2656 case P4M890_FUNCTION3:
2657 case P4M900_FUNCTION3:
2658 case VX800_FUNCTION3:
2659 /*case CN750_FUNCTION3: */
2660 outl(configid + 0xA0, (unsigned long)0xCF8);
2661 FBSize = inl((unsigned long)0xCFC);
2662 DeviceFound = true; /* Found device id */
2663 break;
2664
2665 default:
2666 break;
2667 }
2668
2669 if (DeviceFound)
2670 break;
2671 }
2672
2673 DEBUG_MSG(KERN_INFO "Device ID = %lx\n", deviceid);
2674
2675 FBSize = FBSize & 0x00007000;
2676 DEBUG_MSG(KERN_INFO "FB Size = %x\n", FBSize);
2677
2678 if (viaparinfo->chip_info->gfx_chip_name < UNICHROME_CX700) {
2679 switch (FBSize) {
2680 case 0x00004000:
2681 VideoMemSize = (16 << 20); /*16M */
2682 break;
2683
2684 case 0x00005000:
2685 VideoMemSize = (32 << 20); /*32M */
2686 break;
2687
2688 case 0x00006000:
2689 VideoMemSize = (64 << 20); /*64M */
2690 break;
2691
2692 default:
2693 VideoMemSize = (32 << 20); /*32M */
2694 break;
2695 }
2696 } else {
2697 switch (FBSize) {
2698 case 0x00001000:
2699 VideoMemSize = (8 << 20); /*8M */
2700 break;
2701
2702 case 0x00002000:
2703 VideoMemSize = (16 << 20); /*16M */
2704 break;
2705
2706 case 0x00003000:
2707 VideoMemSize = (32 << 20); /*32M */
2708 break;
2709
2710 case 0x00004000:
2711 VideoMemSize = (64 << 20); /*64M */
2712 break;
2713
2714 case 0x00005000:
2715 VideoMemSize = (128 << 20); /*128M */
2716 break;
2717
2718 case 0x00006000:
2719 VideoMemSize = (256 << 20); /*256M */
2720 break;
2721
2722 default:
2723 VideoMemSize = (32 << 20); /*32M */
2724 break;
2725 }
2726 }
2727
2728 return VideoMemSize;
2729}
2730
2731void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
2732 *p_gfx_dpa_setting)
2733{
2734 switch (output_interface) {
2735 case INTERFACE_DVP0:
2736 {
2737 /* DVP0 Clock Polarity and Adjust: */
2738 viafb_write_reg_mask(CR96, VIACR,
2739 p_gfx_dpa_setting->DVP0, 0x0F);
2740
2741 /* DVP0 Clock and Data Pads Driving: */
2742 viafb_write_reg_mask(SR1E, VIASR,
2743 p_gfx_dpa_setting->DVP0ClockDri_S, BIT2);
2744 viafb_write_reg_mask(SR2A, VIASR,
2745 p_gfx_dpa_setting->DVP0ClockDri_S1,
2746 BIT4);
2747 viafb_write_reg_mask(SR1B, VIASR,
2748 p_gfx_dpa_setting->DVP0DataDri_S, BIT1);
2749 viafb_write_reg_mask(SR2A, VIASR,
2750 p_gfx_dpa_setting->DVP0DataDri_S1, BIT5);
2751 break;
2752 }
2753
2754 case INTERFACE_DVP1:
2755 {
2756 /* DVP1 Clock Polarity and Adjust: */
2757 viafb_write_reg_mask(CR9B, VIACR,
2758 p_gfx_dpa_setting->DVP1, 0x0F);
2759
2760 /* DVP1 Clock and Data Pads Driving: */
2761 viafb_write_reg_mask(SR65, VIASR,
2762 p_gfx_dpa_setting->DVP1Driving, 0x0F);
2763 break;
2764 }
2765
2766 case INTERFACE_DFP_HIGH:
2767 {
2768 viafb_write_reg_mask(CR97, VIACR,
2769 p_gfx_dpa_setting->DFPHigh, 0x0F);
2770 break;
2771 }
2772
2773 case INTERFACE_DFP_LOW:
2774 {
2775 viafb_write_reg_mask(CR99, VIACR,
2776 p_gfx_dpa_setting->DFPLow, 0x0F);
2777 break;
2778 }
2779
2780 case INTERFACE_DFP:
2781 {
2782 viafb_write_reg_mask(CR97, VIACR,
2783 p_gfx_dpa_setting->DFPHigh, 0x0F);
2784 viafb_write_reg_mask(CR99, VIACR,
2785 p_gfx_dpa_setting->DFPLow, 0x0F);
2786 break;
2787 }
2788 }
2789}
2790
2791void viafb_memory_pitch_patch(struct fb_info *info)
2792{
2793 if (info->var.xres != info->var.xres_virtual) {
2794 viafb_load_offset_reg(info->var.xres_virtual,
2795 info->var.bits_per_pixel >> 3, IGA1);
2796
2797 if (viafb_SAMM_ON) {
2798 viafb_load_offset_reg(viafb_second_virtual_xres,
2799 viafb_bpp1 >> 3,
2800 IGA2);
2801 } else {
2802 viafb_load_offset_reg(info->var.xres_virtual,
2803 info->var.bits_per_pixel >> 3, IGA2);
2804 }
2805
2806 }
2807}
2808
2809/*According var's xres, yres fill var's other timing information*/
2810void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh,
2811 int mode_index)
2812{
2813 struct VideoModeTable *vmode_tbl = NULL;
2814 struct crt_mode_table *crt_timing = NULL;
2815 struct display_timing crt_reg;
2816 int i = 0, index = 0;
2817 vmode_tbl = &CLE266Modes[search_mode_setting(mode_index)];
2818 crt_timing = vmode_tbl->crtc;
2819 for (i = 0; i < vmode_tbl->mode_array; i++) {
2820 index = i;
2821 if (crt_timing[i].refresh_rate == refresh)
2822 break;
2823 }
2824
2825 crt_reg = crt_timing[index].crtc;
2826 switch (var->bits_per_pixel) {
2827 case 8:
2828 var->red.offset = 0;
2829 var->green.offset = 0;
2830 var->blue.offset = 0;
2831 var->red.length = 6;
2832 var->green.length = 6;
2833 var->blue.length = 6;
2834 break;
2835 case 16:
2836 var->red.offset = 11;
2837 var->green.offset = 5;
2838 var->blue.offset = 0;
2839 var->red.length = 5;
2840 var->green.length = 6;
2841 var->blue.length = 5;
2842 break;
2843 case 32:
2844 var->red.offset = 16;
2845 var->green.offset = 8;
2846 var->blue.offset = 0;
2847 var->red.length = 8;
2848 var->green.length = 8;
2849 var->blue.length = 8;
2850 break;
2851 default:
2852 /* never happed, put here to keep consistent */
2853 break;
2854 }
2855
2856 var->pixclock = viafb_get_pixclock(var->xres, var->yres, refresh);
2857 var->left_margin =
2858 crt_reg.hor_total - (crt_reg.hor_sync_start + crt_reg.hor_sync_end);
2859 var->right_margin = crt_reg.hor_sync_start - crt_reg.hor_addr;
2860 var->hsync_len = crt_reg.hor_sync_end;
2861 var->upper_margin =
2862 crt_reg.ver_total - (crt_reg.ver_sync_start + crt_reg.ver_sync_end);
2863 var->lower_margin = crt_reg.ver_sync_start - crt_reg.ver_addr;
2864 var->vsync_len = crt_reg.ver_sync_end;
2865}
diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h
new file mode 100644
index 000000000000..6ff38fa8569a
--- /dev/null
+++ b/drivers/video/via/hw.h
@@ -0,0 +1,933 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
14 * for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22#ifndef __HW_H__
23#define __HW_H__
24
25#include "global.h"
26
27/***************************************************
28* Definition IGA1 Design Method of CRTC Registers *
29****************************************************/
30#define IGA1_HOR_TOTAL_FORMULA(x) (((x)/8)-5)
31#define IGA1_HOR_ADDR_FORMULA(x) (((x)/8)-1)
32#define IGA1_HOR_BLANK_START_FORMULA(x) (((x)/8)-1)
33#define IGA1_HOR_BLANK_END_FORMULA(x, y) (((x+y)/8)-1)
34#define IGA1_HOR_SYNC_START_FORMULA(x) ((x)/8)
35#define IGA1_HOR_SYNC_END_FORMULA(x, y) ((x+y)/8)
36
37#define IGA1_VER_TOTAL_FORMULA(x) ((x)-2)
38#define IGA1_VER_ADDR_FORMULA(x) ((x)-1)
39#define IGA1_VER_BLANK_START_FORMULA(x) ((x)-1)
40#define IGA1_VER_BLANK_END_FORMULA(x, y) ((x+y)-1)
41#define IGA1_VER_SYNC_START_FORMULA(x) ((x)-1)
42#define IGA1_VER_SYNC_END_FORMULA(x, y) ((x+y)-1)
43
44/***************************************************
45** Definition IGA2 Design Method of CRTC Registers *
46****************************************************/
47#define IGA2_HOR_TOTAL_FORMULA(x) ((x)-1)
48#define IGA2_HOR_ADDR_FORMULA(x) ((x)-1)
49#define IGA2_HOR_BLANK_START_FORMULA(x) ((x)-1)
50#define IGA2_HOR_BLANK_END_FORMULA(x, y) ((x+y)-1)
51#define IGA2_HOR_SYNC_START_FORMULA(x) ((x)-1)
52#define IGA2_HOR_SYNC_END_FORMULA(x, y) ((x+y)-1)
53
54#define IGA2_VER_TOTAL_FORMULA(x) ((x)-1)
55#define IGA2_VER_ADDR_FORMULA(x) ((x)-1)
56#define IGA2_VER_BLANK_START_FORMULA(x) ((x)-1)
57#define IGA2_VER_BLANK_END_FORMULA(x, y) ((x+y)-1)
58#define IGA2_VER_SYNC_START_FORMULA(x) ((x)-1)
59#define IGA2_VER_SYNC_END_FORMULA(x, y) ((x+y)-1)
60
61/**********************************************************/
62/* Definition IGA2 Design Method of CRTC Shadow Registers */
63/**********************************************************/
64#define IGA2_HOR_TOTAL_SHADOW_FORMULA(x) ((x/8)-5)
65#define IGA2_HOR_BLANK_END_SHADOW_FORMULA(x, y) (((x+y)/8)-1)
66#define IGA2_VER_TOTAL_SHADOW_FORMULA(x) ((x)-2)
67#define IGA2_VER_ADDR_SHADOW_FORMULA(x) ((x)-1)
68#define IGA2_VER_BLANK_START_SHADOW_FORMULA(x) ((x)-1)
69#define IGA2_VER_BLANK_END_SHADOW_FORMULA(x, y) ((x+y)-1)
70#define IGA2_VER_SYNC_START_SHADOW_FORMULA(x) (x)
71#define IGA2_VER_SYNC_END_SHADOW_FORMULA(x, y) (x+y)
72
73/* Define Register Number for IGA1 CRTC Timing */
74
75/* location: {CR00,0,7},{CR36,3,3} */
76#define IGA1_HOR_TOTAL_REG_NUM 2
77/* location: {CR01,0,7} */
78#define IGA1_HOR_ADDR_REG_NUM 1
79/* location: {CR02,0,7} */
80#define IGA1_HOR_BLANK_START_REG_NUM 1
81/* location: {CR03,0,4},{CR05,7,7},{CR33,5,5} */
82#define IGA1_HOR_BLANK_END_REG_NUM 3
83/* location: {CR04,0,7},{CR33,4,4} */
84#define IGA1_HOR_SYNC_START_REG_NUM 2
85/* location: {CR05,0,4} */
86#define IGA1_HOR_SYNC_END_REG_NUM 1
87/* location: {CR06,0,7},{CR07,0,0},{CR07,5,5},{CR35,0,0} */
88#define IGA1_VER_TOTAL_REG_NUM 4
89/* location: {CR12,0,7},{CR07,1,1},{CR07,6,6},{CR35,2,2} */
90#define IGA1_VER_ADDR_REG_NUM 4
91/* location: {CR15,0,7},{CR07,3,3},{CR09,5,5},{CR35,3,3} */
92#define IGA1_VER_BLANK_START_REG_NUM 4
93/* location: {CR16,0,7} */
94#define IGA1_VER_BLANK_END_REG_NUM 1
95/* location: {CR10,0,7},{CR07,2,2},{CR07,7,7},{CR35,1,1} */
96#define IGA1_VER_SYNC_START_REG_NUM 4
97/* location: {CR11,0,3} */
98#define IGA1_VER_SYNC_END_REG_NUM 1
99
100/* Define Register Number for IGA2 Shadow CRTC Timing */
101
102/* location: {CR6D,0,7},{CR71,3,3} */
103#define IGA2_SHADOW_HOR_TOTAL_REG_NUM 2
104/* location: {CR6E,0,7} */
105#define IGA2_SHADOW_HOR_BLANK_END_REG_NUM 1
106/* location: {CR6F,0,7},{CR71,0,2} */
107#define IGA2_SHADOW_VER_TOTAL_REG_NUM 2
108/* location: {CR70,0,7},{CR71,4,6} */
109#define IGA2_SHADOW_VER_ADDR_REG_NUM 2
110/* location: {CR72,0,7},{CR74,4,6} */
111#define IGA2_SHADOW_VER_BLANK_START_REG_NUM 2
112/* location: {CR73,0,7},{CR74,0,2} */
113#define IGA2_SHADOW_VER_BLANK_END_REG_NUM 2
114/* location: {CR75,0,7},{CR76,4,6} */
115#define IGA2_SHADOW_VER_SYNC_START_REG_NUM 2
116/* location: {CR76,0,3} */
117#define IGA2_SHADOW_VER_SYNC_END_REG_NUM 1
118
119/* Define Register Number for IGA2 CRTC Timing */
120
121/* location: {CR50,0,7},{CR55,0,3} */
122#define IGA2_HOR_TOTAL_REG_NUM 2
123/* location: {CR51,0,7},{CR55,4,6} */
124#define IGA2_HOR_ADDR_REG_NUM 2
125/* location: {CR52,0,7},{CR54,0,2} */
126#define IGA2_HOR_BLANK_START_REG_NUM 2
127/* location: CLE266: {CR53,0,7},{CR54,3,5} => CLE266's CR5D[6]
128is reserved, so it may have problem to set 1600x1200 on IGA2. */
129/* Others: {CR53,0,7},{CR54,3,5},{CR5D,6,6} */
130#define IGA2_HOR_BLANK_END_REG_NUM 3
131/* location: {CR56,0,7},{CR54,6,7},{CR5C,7,7} */
132/* VT3314 and Later: {CR56,0,7},{CR54,6,7},{CR5C,7,7}, {CR5D,7,7} */
133#define IGA2_HOR_SYNC_START_REG_NUM 4
134
135/* location: {CR57,0,7},{CR5C,6,6} */
136#define IGA2_HOR_SYNC_END_REG_NUM 2
137/* location: {CR58,0,7},{CR5D,0,2} */
138#define IGA2_VER_TOTAL_REG_NUM 2
139/* location: {CR59,0,7},{CR5D,3,5} */
140#define IGA2_VER_ADDR_REG_NUM 2
141/* location: {CR5A,0,7},{CR5C,0,2} */
142#define IGA2_VER_BLANK_START_REG_NUM 2
143/* location: {CR5E,0,7},{CR5C,3,5} */
144#define IGA2_VER_BLANK_END_REG_NUM 2
145/* location: {CR5E,0,7},{CR5F,5,7} */
146#define IGA2_VER_SYNC_START_REG_NUM 2
147/* location: {CR5F,0,4} */
148#define IGA2_VER_SYNC_END_REG_NUM 1
149
150/* Define Offset and Fetch Count Register*/
151
152/* location: {CR13,0,7},{CR35,5,7} */
153#define IGA1_OFFSET_REG_NUM 2
154/* 8 bytes alignment. */
155#define IGA1_OFFSER_ALIGN_BYTE 8
156/* x: H resolution, y: color depth */
157#define IGA1_OFFSET_FORMULA(x, y) ((x*y)/IGA1_OFFSER_ALIGN_BYTE)
158/* location: {SR1C,0,7},{SR1D,0,1} */
159#define IGA1_FETCH_COUNT_REG_NUM 2
160/* 16 bytes alignment. */
161#define IGA1_FETCH_COUNT_ALIGN_BYTE 16
162/* x: H resolution, y: color depth */
163#define IGA1_FETCH_COUNT_PATCH_VALUE 4
164#define IGA1_FETCH_COUNT_FORMULA(x, y) \
165 (((x*y)/IGA1_FETCH_COUNT_ALIGN_BYTE) + IGA1_FETCH_COUNT_PATCH_VALUE)
166
167/* location: {CR66,0,7},{CR67,0,1} */
168#define IGA2_OFFSET_REG_NUM 2
169#define IGA2_OFFSET_ALIGN_BYTE 8
170/* x: H resolution, y: color depth */
171#define IGA2_OFFSET_FORMULA(x, y) ((x*y)/IGA2_OFFSET_ALIGN_BYTE)
172/* location: {CR65,0,7},{CR67,2,3} */
173#define IGA2_FETCH_COUNT_REG_NUM 2
174#define IGA2_FETCH_COUNT_ALIGN_BYTE 16
175#define IGA2_FETCH_COUNT_PATCH_VALUE 0
176#define IGA2_FETCH_COUNT_FORMULA(x, y) \
177 (((x*y)/IGA2_FETCH_COUNT_ALIGN_BYTE) + IGA2_FETCH_COUNT_PATCH_VALUE)
178
179/* Staring Address*/
180
181/* location: {CR0C,0,7},{CR0D,0,7},{CR34,0,7},{CR48,0,1} */
182#define IGA1_STARTING_ADDR_REG_NUM 4
183/* location: {CR62,1,7},{CR63,0,7},{CR64,0,7} */
184#define IGA2_STARTING_ADDR_REG_NUM 3
185
186/* Define Display OFFSET*/
187/* These value are by HW suggested value*/
188/* location: {SR17,0,7} */
189#define K800_IGA1_FIFO_MAX_DEPTH 384
190/* location: {SR16,0,5},{SR16,7,7} */
191#define K800_IGA1_FIFO_THRESHOLD 328
192/* location: {SR18,0,5},{SR18,7,7} */
193#define K800_IGA1_FIFO_HIGH_THRESHOLD 296
194/* location: {SR22,0,4}. (128/4) =64, K800 must be set zero, */
195 /* because HW only 5 bits */
196#define K800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 0
197
198/* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */
199#define K800_IGA2_FIFO_MAX_DEPTH 384
200/* location: {CR68,0,3},{CR95,4,6} */
201#define K800_IGA2_FIFO_THRESHOLD 328
202/* location: {CR92,0,3},{CR95,0,2} */
203#define K800_IGA2_FIFO_HIGH_THRESHOLD 296
204/* location: {CR94,0,6} */
205#define K800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 128
206
207/* location: {SR17,0,7} */
208#define P880_IGA1_FIFO_MAX_DEPTH 192
209/* location: {SR16,0,5},{SR16,7,7} */
210#define P880_IGA1_FIFO_THRESHOLD 128
211/* location: {SR18,0,5},{SR18,7,7} */
212#define P880_IGA1_FIFO_HIGH_THRESHOLD 64
213/* location: {SR22,0,4}. (128/4) =64, K800 must be set zero, */
214 /* because HW only 5 bits */
215#define P880_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 0
216
217/* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */
218#define P880_IGA2_FIFO_MAX_DEPTH 96
219/* location: {CR68,0,3},{CR95,4,6} */
220#define P880_IGA2_FIFO_THRESHOLD 64
221/* location: {CR92,0,3},{CR95,0,2} */
222#define P880_IGA2_FIFO_HIGH_THRESHOLD 32
223/* location: {CR94,0,6} */
224#define P880_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 128
225
226/* VT3314 chipset*/
227
228/* location: {SR17,0,7} */
229#define CN700_IGA1_FIFO_MAX_DEPTH 96
230/* location: {SR16,0,5},{SR16,7,7} */
231#define CN700_IGA1_FIFO_THRESHOLD 80
232/* location: {SR18,0,5},{SR18,7,7} */
233#define CN700_IGA1_FIFO_HIGH_THRESHOLD 64
234/* location: {SR22,0,4}. (128/4) =64, P800 must be set zero,
235 because HW only 5 bits */
236#define CN700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 0
237/* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */
238#define CN700_IGA2_FIFO_MAX_DEPTH 96
239/* location: {CR68,0,3},{CR95,4,6} */
240#define CN700_IGA2_FIFO_THRESHOLD 80
241/* location: {CR92,0,3},{CR95,0,2} */
242#define CN700_IGA2_FIFO_HIGH_THRESHOLD 32
243/* location: {CR94,0,6} */
244#define CN700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 128
245
246/* For VT3324, these values are suggested by HW */
247/* location: {SR17,0,7} */
248#define CX700_IGA1_FIFO_MAX_DEPTH 192
249/* location: {SR16,0,5},{SR16,7,7} */
250#define CX700_IGA1_FIFO_THRESHOLD 128
251/* location: {SR18,0,5},{SR18,7,7} */
252#define CX700_IGA1_FIFO_HIGH_THRESHOLD 128
253/* location: {SR22,0,4} */
254#define CX700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 124
255
256/* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */
257#define CX700_IGA2_FIFO_MAX_DEPTH 96
258/* location: {CR68,0,3},{CR95,4,6} */
259#define CX700_IGA2_FIFO_THRESHOLD 64
260/* location: {CR92,0,3},{CR95,0,2} */
261#define CX700_IGA2_FIFO_HIGH_THRESHOLD 32
262/* location: {CR94,0,6} */
263#define CX700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 128
264
265/* VT3336 chipset*/
266/* location: {SR17,0,7} */
267#define K8M890_IGA1_FIFO_MAX_DEPTH 360
268/* location: {SR16,0,5},{SR16,7,7} */
269#define K8M890_IGA1_FIFO_THRESHOLD 328
270/* location: {SR18,0,5},{SR18,7,7} */
271#define K8M890_IGA1_FIFO_HIGH_THRESHOLD 296
272/* location: {SR22,0,4}. */
273#define K8M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 124
274
275/* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */
276#define K8M890_IGA2_FIFO_MAX_DEPTH 360
277/* location: {CR68,0,3},{CR95,4,6} */
278#define K8M890_IGA2_FIFO_THRESHOLD 328
279/* location: {CR92,0,3},{CR95,0,2} */
280#define K8M890_IGA2_FIFO_HIGH_THRESHOLD 296
281/* location: {CR94,0,6} */
282#define K8M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 124
283
284/* VT3327 chipset*/
285/* location: {SR17,0,7} */
286#define P4M890_IGA1_FIFO_MAX_DEPTH 96
287/* location: {SR16,0,5},{SR16,7,7} */
288#define P4M890_IGA1_FIFO_THRESHOLD 76
289/* location: {SR18,0,5},{SR18,7,7} */
290#define P4M890_IGA1_FIFO_HIGH_THRESHOLD 64
291/* location: {SR22,0,4}. (32/4) =8 */
292#define P4M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 32
293/* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */
294#define P4M890_IGA2_FIFO_MAX_DEPTH 96
295/* location: {CR68,0,3},{CR95,4,6} */
296#define P4M890_IGA2_FIFO_THRESHOLD 76
297/* location: {CR92,0,3},{CR95,0,2} */
298#define P4M890_IGA2_FIFO_HIGH_THRESHOLD 64
299/* location: {CR94,0,6} */
300#define P4M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 32
301
302/* VT3364 chipset*/
303/* location: {SR17,0,7} */
304#define P4M900_IGA1_FIFO_MAX_DEPTH 96
305/* location: {SR16,0,5},{SR16,7,7} */
306#define P4M900_IGA1_FIFO_THRESHOLD 76
307/* location: {SR18,0,5},{SR18,7,7} */
308#define P4M900_IGA1_FIFO_HIGH_THRESHOLD 76
309/* location: {SR22,0,4}. */
310#define P4M900_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 32
311/* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */
312#define P4M900_IGA2_FIFO_MAX_DEPTH 96
313/* location: {CR68,0,3},{CR95,4,6} */
314#define P4M900_IGA2_FIFO_THRESHOLD 76
315/* location: {CR92,0,3},{CR95,0,2} */
316#define P4M900_IGA2_FIFO_HIGH_THRESHOLD 76
317/* location: {CR94,0,6} */
318#define P4M900_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 32
319
320/* For VT3353, these values are suggested by HW */
321/* location: {SR17,0,7} */
322#define VX800_IGA1_FIFO_MAX_DEPTH 192
323/* location: {SR16,0,5},{SR16,7,7} */
324#define VX800_IGA1_FIFO_THRESHOLD 152
325/* location: {SR18,0,5},{SR18,7,7} */
326#define VX800_IGA1_FIFO_HIGH_THRESHOLD 152
327/* location: {SR22,0,4} */
328#define VX800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 64
329/* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */
330#define VX800_IGA2_FIFO_MAX_DEPTH 96
331/* location: {CR68,0,3},{CR95,4,6} */
332#define VX800_IGA2_FIFO_THRESHOLD 64
333/* location: {CR92,0,3},{CR95,0,2} */
334#define VX800_IGA2_FIFO_HIGH_THRESHOLD 32
335/* location: {CR94,0,6} */
336#define VX800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 128
337
338#define IGA1_FIFO_DEPTH_SELECT_REG_NUM 1
339#define IGA1_FIFO_THRESHOLD_REG_NUM 2
340#define IGA1_FIFO_HIGH_THRESHOLD_REG_NUM 2
341#define IGA1_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM 1
342
343#define IGA2_FIFO_DEPTH_SELECT_REG_NUM 3
344#define IGA2_FIFO_THRESHOLD_REG_NUM 2
345#define IGA2_FIFO_HIGH_THRESHOLD_REG_NUM 2
346#define IGA2_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM 1
347
348#define IGA1_FIFO_DEPTH_SELECT_FORMULA(x) ((x/2)-1)
349#define IGA1_FIFO_THRESHOLD_FORMULA(x) (x/4)
350#define IGA1_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA(x) (x/4)
351#define IGA1_FIFO_HIGH_THRESHOLD_FORMULA(x) (x/4)
352#define IGA2_FIFO_DEPTH_SELECT_FORMULA(x) (((x/2)/4)-1)
353#define IGA2_FIFO_THRESHOLD_FORMULA(x) (x/4)
354#define IGA2_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA(x) (x/4)
355#define IGA2_FIFO_HIGH_THRESHOLD_FORMULA(x) (x/4)
356
357/************************************************************************/
358/* LCD Timing */
359/************************************************************************/
360
361/* 500 ms = 500000 us */
362#define LCD_POWER_SEQ_TD0 500000
363/* 50 ms = 50000 us */
364#define LCD_POWER_SEQ_TD1 50000
365/* 0 us */
366#define LCD_POWER_SEQ_TD2 0
367/* 210 ms = 210000 us */
368#define LCD_POWER_SEQ_TD3 210000
369/* 2^10 * (1/14.31818M) = 71.475 us (K400.revA) */
370#define CLE266_POWER_SEQ_UNIT 71
371/* 2^11 * (1/14.31818M) = 142.95 us (K400.revB) */
372#define K800_POWER_SEQ_UNIT 142
373/* 2^13 * (1/14.31818M) = 572.1 us */
374#define P880_POWER_SEQ_UNIT 572
375
376#define CLE266_POWER_SEQ_FORMULA(x) ((x)/CLE266_POWER_SEQ_UNIT)
377#define K800_POWER_SEQ_FORMULA(x) ((x)/K800_POWER_SEQ_UNIT)
378#define P880_POWER_SEQ_FORMULA(x) ((x)/P880_POWER_SEQ_UNIT)
379
380/* location: {CR8B,0,7},{CR8F,0,3} */
381#define LCD_POWER_SEQ_TD0_REG_NUM 2
382/* location: {CR8C,0,7},{CR8F,4,7} */
383#define LCD_POWER_SEQ_TD1_REG_NUM 2
384/* location: {CR8D,0,7},{CR90,0,3} */
385#define LCD_POWER_SEQ_TD2_REG_NUM 2
386/* location: {CR8E,0,7},{CR90,4,7} */
387#define LCD_POWER_SEQ_TD3_REG_NUM 2
388
389/* LCD Scaling factor*/
390/* x: indicate setting horizontal size*/
391/* y: indicate panel horizontal size*/
392
393/* Horizontal scaling factor 10 bits (2^10) */
394#define CLE266_LCD_HOR_SCF_FORMULA(x, y) (((x-1)*1024)/(y-1))
395/* Vertical scaling factor 10 bits (2^10) */
396#define CLE266_LCD_VER_SCF_FORMULA(x, y) (((x-1)*1024)/(y-1))
397/* Horizontal scaling factor 10 bits (2^12) */
398#define K800_LCD_HOR_SCF_FORMULA(x, y) (((x-1)*4096)/(y-1))
399/* Vertical scaling factor 10 bits (2^11) */
400#define K800_LCD_VER_SCF_FORMULA(x, y) (((x-1)*2048)/(y-1))
401
402/* location: {CR9F,0,1},{CR77,0,7},{CR79,4,5} */
403#define LCD_HOR_SCALING_FACTOR_REG_NUM 3
404/* location: {CR79,3,3},{CR78,0,7},{CR79,6,7} */
405#define LCD_VER_SCALING_FACTOR_REG_NUM 3
406/* location: {CR77,0,7},{CR79,4,5} */
407#define LCD_HOR_SCALING_FACTOR_REG_NUM_CLE 2
408/* location: {CR78,0,7},{CR79,6,7} */
409#define LCD_VER_SCALING_FACTOR_REG_NUM_CLE 2
410
411/************************************************
412 ***** Define IGA1 Display Timing *****
413 ************************************************/
414struct io_register {
415 u8 io_addr;
416 u8 start_bit;
417 u8 end_bit;
418};
419
420/* IGA1 Horizontal Total */
421struct iga1_hor_total {
422 int reg_num;
423 struct io_register reg[IGA1_HOR_TOTAL_REG_NUM];
424};
425
426/* IGA1 Horizontal Addressable Video */
427struct iga1_hor_addr {
428 int reg_num;
429 struct io_register reg[IGA1_HOR_ADDR_REG_NUM];
430};
431
432/* IGA1 Horizontal Blank Start */
433struct iga1_hor_blank_start {
434 int reg_num;
435 struct io_register reg[IGA1_HOR_BLANK_START_REG_NUM];
436};
437
438/* IGA1 Horizontal Blank End */
439struct iga1_hor_blank_end {
440 int reg_num;
441 struct io_register reg[IGA1_HOR_BLANK_END_REG_NUM];
442};
443
444/* IGA1 Horizontal Sync Start */
445struct iga1_hor_sync_start {
446 int reg_num;
447 struct io_register reg[IGA1_HOR_SYNC_START_REG_NUM];
448};
449
450/* IGA1 Horizontal Sync End */
451struct iga1_hor_sync_end {
452 int reg_num;
453 struct io_register reg[IGA1_HOR_SYNC_END_REG_NUM];
454};
455
456/* IGA1 Vertical Total */
457struct iga1_ver_total {
458 int reg_num;
459 struct io_register reg[IGA1_VER_TOTAL_REG_NUM];
460};
461
462/* IGA1 Vertical Addressable Video */
463struct iga1_ver_addr {
464 int reg_num;
465 struct io_register reg[IGA1_VER_ADDR_REG_NUM];
466};
467
468/* IGA1 Vertical Blank Start */
469struct iga1_ver_blank_start {
470 int reg_num;
471 struct io_register reg[IGA1_VER_BLANK_START_REG_NUM];
472};
473
474/* IGA1 Vertical Blank End */
475struct iga1_ver_blank_end {
476 int reg_num;
477 struct io_register reg[IGA1_VER_BLANK_END_REG_NUM];
478};
479
480/* IGA1 Vertical Sync Start */
481struct iga1_ver_sync_start {
482 int reg_num;
483 struct io_register reg[IGA1_VER_SYNC_START_REG_NUM];
484};
485
486/* IGA1 Vertical Sync End */
487struct iga1_ver_sync_end {
488 int reg_num;
489 struct io_register reg[IGA1_VER_SYNC_END_REG_NUM];
490};
491
492/*****************************************************
493** Define IGA2 Shadow Display Timing ****
494*****************************************************/
495
496/* IGA2 Shadow Horizontal Total */
497struct iga2_shadow_hor_total {
498 int reg_num;
499 struct io_register reg[IGA2_SHADOW_HOR_TOTAL_REG_NUM];
500};
501
502/* IGA2 Shadow Horizontal Blank End */
503struct iga2_shadow_hor_blank_end {
504 int reg_num;
505 struct io_register reg[IGA2_SHADOW_HOR_BLANK_END_REG_NUM];
506};
507
508/* IGA2 Shadow Vertical Total */
509struct iga2_shadow_ver_total {
510 int reg_num;
511 struct io_register reg[IGA2_SHADOW_VER_TOTAL_REG_NUM];
512};
513
514/* IGA2 Shadow Vertical Addressable Video */
515struct iga2_shadow_ver_addr {
516 int reg_num;
517 struct io_register reg[IGA2_SHADOW_VER_ADDR_REG_NUM];
518};
519
520/* IGA2 Shadow Vertical Blank Start */
521struct iga2_shadow_ver_blank_start {
522 int reg_num;
523 struct io_register reg[IGA2_SHADOW_VER_BLANK_START_REG_NUM];
524};
525
526/* IGA2 Shadow Vertical Blank End */
527struct iga2_shadow_ver_blank_end {
528 int reg_num;
529 struct io_register reg[IGA2_SHADOW_VER_BLANK_END_REG_NUM];
530};
531
532/* IGA2 Shadow Vertical Sync Start */
533struct iga2_shadow_ver_sync_start {
534 int reg_num;
535 struct io_register reg[IGA2_SHADOW_VER_SYNC_START_REG_NUM];
536};
537
538/* IGA2 Shadow Vertical Sync End */
539struct iga2_shadow_ver_sync_end {
540 int reg_num;
541 struct io_register reg[IGA2_SHADOW_VER_SYNC_END_REG_NUM];
542};
543
544/*****************************************************
545** Define IGA2 Display Timing ****
546******************************************************/
547
548/* IGA2 Horizontal Total */
549struct iga2_hor_total {
550 int reg_num;
551 struct io_register reg[IGA2_HOR_TOTAL_REG_NUM];
552};
553
554/* IGA2 Horizontal Addressable Video */
555struct iga2_hor_addr {
556 int reg_num;
557 struct io_register reg[IGA2_HOR_ADDR_REG_NUM];
558};
559
560/* IGA2 Horizontal Blank Start */
561struct iga2_hor_blank_start {
562 int reg_num;
563 struct io_register reg[IGA2_HOR_BLANK_START_REG_NUM];
564};
565
566/* IGA2 Horizontal Blank End */
567struct iga2_hor_blank_end {
568 int reg_num;
569 struct io_register reg[IGA2_HOR_BLANK_END_REG_NUM];
570};
571
572/* IGA2 Horizontal Sync Start */
573struct iga2_hor_sync_start {
574 int reg_num;
575 struct io_register reg[IGA2_HOR_SYNC_START_REG_NUM];
576};
577
578/* IGA2 Horizontal Sync End */
579struct iga2_hor_sync_end {
580 int reg_num;
581 struct io_register reg[IGA2_HOR_SYNC_END_REG_NUM];
582};
583
584/* IGA2 Vertical Total */
585struct iga2_ver_total {
586 int reg_num;
587 struct io_register reg[IGA2_VER_TOTAL_REG_NUM];
588};
589
590/* IGA2 Vertical Addressable Video */
591struct iga2_ver_addr {
592 int reg_num;
593 struct io_register reg[IGA2_VER_ADDR_REG_NUM];
594};
595
596/* IGA2 Vertical Blank Start */
597struct iga2_ver_blank_start {
598 int reg_num;
599 struct io_register reg[IGA2_VER_BLANK_START_REG_NUM];
600};
601
602/* IGA2 Vertical Blank End */
603struct iga2_ver_blank_end {
604 int reg_num;
605 struct io_register reg[IGA2_VER_BLANK_END_REG_NUM];
606};
607
608/* IGA2 Vertical Sync Start */
609struct iga2_ver_sync_start {
610 int reg_num;
611 struct io_register reg[IGA2_VER_SYNC_START_REG_NUM];
612};
613
614/* IGA2 Vertical Sync End */
615struct iga2_ver_sync_end {
616 int reg_num;
617 struct io_register reg[IGA2_VER_SYNC_END_REG_NUM];
618};
619
620/* IGA1 Offset Register */
621struct iga1_offset {
622 int reg_num;
623 struct io_register reg[IGA1_OFFSET_REG_NUM];
624};
625
626/* IGA2 Offset Register */
627struct iga2_offset {
628 int reg_num;
629 struct io_register reg[IGA2_OFFSET_REG_NUM];
630};
631
632struct offset {
633 struct iga1_offset iga1_offset_reg;
634 struct iga2_offset iga2_offset_reg;
635};
636
637/* IGA1 Fetch Count Register */
638struct iga1_fetch_count {
639 int reg_num;
640 struct io_register reg[IGA1_FETCH_COUNT_REG_NUM];
641};
642
643/* IGA2 Fetch Count Register */
644struct iga2_fetch_count {
645 int reg_num;
646 struct io_register reg[IGA2_FETCH_COUNT_REG_NUM];
647};
648
649struct fetch_count {
650 struct iga1_fetch_count iga1_fetch_count_reg;
651 struct iga2_fetch_count iga2_fetch_count_reg;
652};
653
654/* Starting Address Register */
655struct iga1_starting_addr {
656 int reg_num;
657 struct io_register reg[IGA1_STARTING_ADDR_REG_NUM];
658};
659
660struct iga2_starting_addr {
661 int reg_num;
662 struct io_register reg[IGA2_STARTING_ADDR_REG_NUM];
663};
664
665struct starting_addr {
666 struct iga1_starting_addr iga1_starting_addr_reg;
667 struct iga2_starting_addr iga2_starting_addr_reg;
668};
669
670/* LCD Power Sequence Timer */
671struct lcd_pwd_seq_td0 {
672 int reg_num;
673 struct io_register reg[LCD_POWER_SEQ_TD0_REG_NUM];
674};
675
676struct lcd_pwd_seq_td1 {
677 int reg_num;
678 struct io_register reg[LCD_POWER_SEQ_TD1_REG_NUM];
679};
680
681struct lcd_pwd_seq_td2 {
682 int reg_num;
683 struct io_register reg[LCD_POWER_SEQ_TD2_REG_NUM];
684};
685
686struct lcd_pwd_seq_td3 {
687 int reg_num;
688 struct io_register reg[LCD_POWER_SEQ_TD3_REG_NUM];
689};
690
691struct _lcd_pwd_seq_timer {
692 struct lcd_pwd_seq_td0 td0;
693 struct lcd_pwd_seq_td1 td1;
694 struct lcd_pwd_seq_td2 td2;
695 struct lcd_pwd_seq_td3 td3;
696};
697
698/* LCD Scaling Factor */
699struct _lcd_hor_scaling_factor {
700 int reg_num;
701 struct io_register reg[LCD_HOR_SCALING_FACTOR_REG_NUM];
702};
703
704struct _lcd_ver_scaling_factor {
705 int reg_num;
706 struct io_register reg[LCD_VER_SCALING_FACTOR_REG_NUM];
707};
708
709struct _lcd_scaling_factor {
710 struct _lcd_hor_scaling_factor lcd_hor_scaling_factor;
711 struct _lcd_ver_scaling_factor lcd_ver_scaling_factor;
712};
713
714struct pll_map {
715 u32 clk;
716 u32 cle266_pll;
717 u32 k800_pll;
718 u32 cx700_pll;
719};
720
721struct rgbLUT {
722 u8 red;
723 u8 green;
724 u8 blue;
725};
726
727struct lcd_pwd_seq_timer {
728 u16 td0;
729 u16 td1;
730 u16 td2;
731 u16 td3;
732};
733
734/* Display FIFO Relation Registers*/
735struct iga1_fifo_depth_select {
736 int reg_num;
737 struct io_register reg[IGA1_FIFO_DEPTH_SELECT_REG_NUM];
738};
739
740struct iga1_fifo_threshold_select {
741 int reg_num;
742 struct io_register reg[IGA1_FIFO_THRESHOLD_REG_NUM];
743};
744
745struct iga1_fifo_high_threshold_select {
746 int reg_num;
747 struct io_register reg[IGA1_FIFO_HIGH_THRESHOLD_REG_NUM];
748};
749
750struct iga1_display_queue_expire_num {
751 int reg_num;
752 struct io_register reg[IGA1_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM];
753};
754
755struct iga2_fifo_depth_select {
756 int reg_num;
757 struct io_register reg[IGA2_FIFO_DEPTH_SELECT_REG_NUM];
758};
759
760struct iga2_fifo_threshold_select {
761 int reg_num;
762 struct io_register reg[IGA2_FIFO_THRESHOLD_REG_NUM];
763};
764
765struct iga2_fifo_high_threshold_select {
766 int reg_num;
767 struct io_register reg[IGA2_FIFO_HIGH_THRESHOLD_REG_NUM];
768};
769
770struct iga2_display_queue_expire_num {
771 int reg_num;
772 struct io_register reg[IGA2_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM];
773};
774
775struct fifo_depth_select {
776 struct iga1_fifo_depth_select iga1_fifo_depth_select_reg;
777 struct iga2_fifo_depth_select iga2_fifo_depth_select_reg;
778};
779
780struct fifo_threshold_select {
781 struct iga1_fifo_threshold_select iga1_fifo_threshold_select_reg;
782 struct iga2_fifo_threshold_select iga2_fifo_threshold_select_reg;
783};
784
785struct fifo_high_threshold_select {
786 struct iga1_fifo_high_threshold_select
787 iga1_fifo_high_threshold_select_reg;
788 struct iga2_fifo_high_threshold_select
789 iga2_fifo_high_threshold_select_reg;
790};
791
792struct display_queue_expire_num {
793 struct iga1_display_queue_expire_num
794 iga1_display_queue_expire_num_reg;
795 struct iga2_display_queue_expire_num
796 iga2_display_queue_expire_num_reg;
797};
798
799struct iga1_crtc_timing {
800 struct iga1_hor_total hor_total;
801 struct iga1_hor_addr hor_addr;
802 struct iga1_hor_blank_start hor_blank_start;
803 struct iga1_hor_blank_end hor_blank_end;
804 struct iga1_hor_sync_start hor_sync_start;
805 struct iga1_hor_sync_end hor_sync_end;
806 struct iga1_ver_total ver_total;
807 struct iga1_ver_addr ver_addr;
808 struct iga1_ver_blank_start ver_blank_start;
809 struct iga1_ver_blank_end ver_blank_end;
810 struct iga1_ver_sync_start ver_sync_start;
811 struct iga1_ver_sync_end ver_sync_end;
812};
813
814struct iga2_shadow_crtc_timing {
815 struct iga2_shadow_hor_total hor_total_shadow;
816 struct iga2_shadow_hor_blank_end hor_blank_end_shadow;
817 struct iga2_shadow_ver_total ver_total_shadow;
818 struct iga2_shadow_ver_addr ver_addr_shadow;
819 struct iga2_shadow_ver_blank_start ver_blank_start_shadow;
820 struct iga2_shadow_ver_blank_end ver_blank_end_shadow;
821 struct iga2_shadow_ver_sync_start ver_sync_start_shadow;
822 struct iga2_shadow_ver_sync_end ver_sync_end_shadow;
823};
824
825struct iga2_crtc_timing {
826 struct iga2_hor_total hor_total;
827 struct iga2_hor_addr hor_addr;
828 struct iga2_hor_blank_start hor_blank_start;
829 struct iga2_hor_blank_end hor_blank_end;
830 struct iga2_hor_sync_start hor_sync_start;
831 struct iga2_hor_sync_end hor_sync_end;
832 struct iga2_ver_total ver_total;
833 struct iga2_ver_addr ver_addr;
834 struct iga2_ver_blank_start ver_blank_start;
835 struct iga2_ver_blank_end ver_blank_end;
836 struct iga2_ver_sync_start ver_sync_start;
837 struct iga2_ver_sync_end ver_sync_end;
838};
839
840/* device ID */
841#define CLE266 0x3123
842#define KM400 0x3205
843#define CN400_FUNCTION2 0x2259
844#define CN400_FUNCTION3 0x3259
845/* support VT3314 chipset */
846#define CN700_FUNCTION2 0x2314
847#define CN700_FUNCTION3 0x3208
848/* VT3324 chipset */
849#define CX700_FUNCTION2 0x2324
850#define CX700_FUNCTION3 0x3324
851/* VT3204 chipset*/
852#define KM800_FUNCTION3 0x3204
853/* VT3336 chipset*/
854#define KM890_FUNCTION3 0x3336
855/* VT3327 chipset*/
856#define P4M890_FUNCTION3 0x3327
857/* VT3293 chipset*/
858#define CN750_FUNCTION3 0x3208
859/* VT3364 chipset*/
860#define P4M900_FUNCTION3 0x3364
861/* VT3353 chipset*/
862#define VX800_FUNCTION3 0x3353
863
864#define NUM_TOTAL_PLL_TABLE ARRAY_SIZE(pll_value)
865
866struct IODATA {
867 u8 Index;
868 u8 Mask;
869 u8 Data;
870};
871
872struct pci_device_id_info {
873 u32 vendor;
874 u32 device;
875 u32 chip_index;
876};
877
878extern unsigned int viafb_second_virtual_xres;
879extern unsigned int viafb_second_offset;
880extern int viafb_second_size;
881extern int viafb_SAMM_ON;
882extern int viafb_dual_fb;
883extern int viafb_LCD2_ON;
884extern int viafb_LCD_ON;
885extern int viafb_DVI_ON;
886extern int viafb_accel;
887extern int viafb_hotplug;
888
889void viafb_write_reg_mask(u8 index, int io_port, u8 data, u8 mask);
890void viafb_set_output_path(int device, int set_iga,
891 int output_interface);
892void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
893 int mode_index, int bpp_byte, int set_iga);
894
895void viafb_set_vclock(u32 CLK, int set_iga);
896void viafb_load_reg(int timing_value, int viafb_load_reg_num,
897 struct io_register *reg,
898 int io_type);
899void viafb_crt_disable(void);
900void viafb_crt_enable(void);
901void init_ad9389(void);
902/* Access I/O Function */
903void viafb_write_reg(u8 index, u16 io_port, u8 data);
904u8 viafb_read_reg(int io_port, u8 index);
905void viafb_lock_crt(void);
906void viafb_unlock_crt(void);
907void viafb_load_offset_reg(int h_addr, int bpp_byte, int set_iga);
908void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga);
909void viafb_write_regx(struct io_reg RegTable[], int ItemNum);
910struct VideoModeTable *viafb_get_modetbl_pointer(int Index);
911u32 viafb_get_clk_value(int clk);
912void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active);
913void viafb_set_color_depth(int bpp_byte, int set_iga);
914void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
915 *p_gfx_dpa_setting);
916
917int viafb_setmode(int vmode_index, int hor_res, int ver_res,
918 int video_bpp, int vmode_index1, int hor_res1,
919 int ver_res1, int video_bpp1);
920void viafb_init_chip_info(void);
921void viafb_init_dac(int set_iga);
922int viafb_get_pixclock(int hres, int vres, int vmode_refresh);
923int viafb_get_refresh(int hres, int vres, u32 float_refresh);
924void viafb_update_device_setting(int hres, int vres, int bpp,
925 int vmode_refresh, int flag);
926void viafb_get_mmio_info(unsigned long *mmio_base,
927 unsigned long *mmio_len);
928
929void viafb_set_iga_path(void);
930void viafb_set_start_addr(void);
931void viafb_get_fb_info(unsigned int *fb_base, unsigned int *fb_len);
932
933#endif /* __HW_H__ */
diff --git a/drivers/video/via/iface.c b/drivers/video/via/iface.c
new file mode 100644
index 000000000000..1570636c8d51
--- /dev/null
+++ b/drivers/video/via/iface.c
@@ -0,0 +1,78 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
14 * for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22#include "global.h"
23
24/* Get frame buffer size from VGA BIOS */
25
26unsigned int viafb_get_memsize(void)
27{
28 unsigned int m;
29
30 /* If memory size provided by user */
31 if (viafb_memsize)
32 m = viafb_memsize * Mb;
33 else {
34 m = (unsigned int)viafb_read_reg(VIASR, SR39);
35 m = m * (4 * Mb);
36
37 if ((m < (16 * Mb)) || (m > (64 * Mb)))
38 m = 16 * Mb;
39 }
40 DEBUG_MSG(KERN_INFO "framebuffer size = %d Mb\n", m / Mb);
41 return m;
42}
43
44/* Get Video Buffer Starting Physical Address(back door)*/
45
46unsigned long viafb_get_videobuf_addr(void)
47{
48 struct pci_dev *pdev = NULL;
49 unsigned char sys_mem;
50 unsigned char video_mem;
51 unsigned long sys_mem_size;
52 unsigned long video_mem_size;
53 /*system memory = 256 MB, video memory 64 MB */
54 unsigned long vmem_starting_adr = 0x0C000000;
55
56 pdev =
57 (struct pci_dev *)pci_get_device(VIA_K800_BRIDGE_VID,
58 VIA_K800_BRIDGE_DID, NULL);
59 if (pdev != NULL) {
60 pci_read_config_byte(pdev, VIA_K800_SYSTEM_MEMORY_REG,
61 &sys_mem);
62 pci_read_config_byte(pdev, VIA_K800_VIDEO_MEMORY_REG,
63 &video_mem);
64 video_mem = (video_mem & 0x70) >> 4;
65 sys_mem_size = ((unsigned long)sys_mem) << 24;
66 if (video_mem != 0)
67 video_mem_size = (1 << (video_mem)) * 1024 * 1024;
68 else
69 video_mem_size = 0;
70
71 vmem_starting_adr = sys_mem_size - video_mem_size;
72 pci_dev_put(pdev);
73 }
74
75 DEBUG_MSG(KERN_INFO "Video Memory Starting Address = %lx \n",
76 vmem_starting_adr);
77 return vmem_starting_adr;
78}
diff --git a/drivers/video/via/iface.h b/drivers/video/via/iface.h
new file mode 100644
index 000000000000..790ec3e3aea2
--- /dev/null
+++ b/drivers/video/via/iface.h
@@ -0,0 +1,38 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
14 * for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22#ifndef __IFACE_H__
23#define __IFACE_H__
24
25#define Kb (1024)
26#define Mb (Kb*Kb)
27
28#define VIA_K800_BRIDGE_VID 0x1106
29#define VIA_K800_BRIDGE_DID 0x3204
30
31#define VIA_K800_SYSTEM_MEMORY_REG 0x47
32#define VIA_K800_VIDEO_MEMORY_REG 0xA1
33
34extern int viafb_memsize;
35unsigned int viafb_get_memsize(void);
36unsigned long viafb_get_videobuf_addr(void);
37
38#endif /* __IFACE_H__ */
diff --git a/drivers/video/via/ioctl.c b/drivers/video/via/ioctl.c
new file mode 100644
index 000000000000..da03c074e32a
--- /dev/null
+++ b/drivers/video/via/ioctl.c
@@ -0,0 +1,112 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
14 * for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22#include "global.h"
23
24int viafb_ioctl_get_viafb_info(u_long arg)
25{
26 struct viafb_ioctl_info viainfo;
27
28 viainfo.viafb_id = VIAID;
29 viainfo.vendor_id = PCI_VIA_VENDOR_ID;
30
31 switch (viaparinfo->chip_info->gfx_chip_name) {
32 case UNICHROME_CLE266:
33 viainfo.device_id = UNICHROME_CLE266_DID;
34 break;
35
36 case UNICHROME_K400:
37 viainfo.device_id = UNICHROME_K400_DID;
38 break;
39
40 case UNICHROME_K800:
41 viainfo.device_id = UNICHROME_K800_DID;
42 break;
43
44 case UNICHROME_PM800:
45 viainfo.device_id = UNICHROME_PM800_DID;
46 break;
47
48 case UNICHROME_CN700:
49 viainfo.device_id = UNICHROME_CN700_DID;
50 break;
51
52 case UNICHROME_CX700:
53 viainfo.device_id = UNICHROME_CX700_DID;
54 break;
55
56 case UNICHROME_K8M890:
57 viainfo.device_id = UNICHROME_K8M890_DID;
58 break;
59
60 case UNICHROME_P4M890:
61 viainfo.device_id = UNICHROME_P4M890_DID;
62 break;
63
64 case UNICHROME_P4M900:
65 viainfo.device_id = UNICHROME_P4M900_DID;
66 break;
67 }
68
69 viainfo.version = VERSION_MAJOR;
70 viainfo.revision = VERSION_MINOR;
71
72 if (copy_to_user((void __user *)arg, &viainfo, sizeof(viainfo)))
73 return -EFAULT;
74
75 return 0;
76}
77
78/* Hot-Plug Priority: DVI > CRT*/
79int viafb_ioctl_hotplug(int hres, int vres, int bpp)
80{
81 int DVIsense, status = 0;
82 DEBUG_MSG(KERN_INFO "viafb_ioctl_hotplug!!\n");
83
84 if (viaparinfo->chip_info->tmds_chip_info.tmds_chip_name !=
85 NON_TMDS_TRANSMITTER) {
86 DVIsense = viafb_dvi_sense();
87
88 if (DVIsense) {
89 DEBUG_MSG(KERN_INFO "DVI Attached...\n");
90 if (viafb_DeviceStatus != DVI_Device) {
91 viafb_DVI_ON = 1;
92 viafb_CRT_ON = 0;
93 viafb_LCD_ON = 0;
94 viafb_DeviceStatus = DVI_Device;
95 return viafb_DeviceStatus;
96 }
97 status = 1;
98 } else
99 DEBUG_MSG(KERN_INFO "DVI De-attached...\n");
100 }
101
102 if ((viafb_DeviceStatus != CRT_Device) && (status == 0)) {
103 viafb_CRT_ON = 1;
104 viafb_DVI_ON = 0;
105 viafb_LCD_ON = 0;
106
107 viafb_DeviceStatus = CRT_Device;
108 return viafb_DeviceStatus;
109 }
110
111 return 0;
112}
diff --git a/drivers/video/via/ioctl.h b/drivers/video/via/ioctl.h
new file mode 100644
index 000000000000..842fe30b9868
--- /dev/null
+++ b/drivers/video/via/ioctl.h
@@ -0,0 +1,210 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
14 * for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22#ifndef __IOCTL_H__
23#define __IOCTL_H__
24
25#ifndef __user
26#define __user
27#endif
28
29/* VIAFB IOCTL definition */
30#define VIAFB_GET_INFO_SIZE 0x56494101 /* 'VIA\01' */
31#define VIAFB_GET_INFO 0x56494102 /* 'VIA\02' */
32#define VIAFB_HOTPLUG 0x56494103 /* 'VIA\03' */
33#define VIAFB_SET_HOTPLUG_FLAG 0x56494104 /* 'VIA\04' */
34#define VIAFB_GET_RESOLUTION 0x56494105 /* 'VIA\05' */
35#define VIAFB_GET_SAMM_INFO 0x56494107 /* 'VIA\07' */
36#define VIAFB_TURN_ON_OUTPUT_DEVICE 0x56494108 /* 'VIA\08' */
37#define VIAFB_TURN_OFF_OUTPUT_DEVICE 0x56494109 /* 'VIA\09' */
38#define VIAFB_SET_DEVICE 0x5649410A
39#define VIAFB_GET_DEVICE 0x5649410B
40#define VIAFB_GET_DRIVER_VERSION 0x56494112 /* 'VIA\12' */
41#define VIAFB_GET_CHIP_INFO 0x56494113 /* 'VIA\13' */
42#define VIAFB_SET_DEVICE_INFO 0x56494114
43#define VIAFB_GET_DEVICE_INFO 0x56494115
44
45#define VIAFB_GET_DEVICE_SUPPORT 0x56494118
46#define VIAFB_GET_DEVICE_CONNECT 0x56494119
47#define VIAFB_GET_PANEL_SUPPORT_EXPAND 0x5649411A
48#define VIAFB_GET_DRIVER_NAME 0x56494122
49#define VIAFB_GET_DEVICE_SUPPORT_STATE 0x56494123
50#define VIAFB_GET_GAMMA_LUT 0x56494124
51#define VIAFB_SET_GAMMA_LUT 0x56494125
52#define VIAFB_GET_GAMMA_SUPPORT_STATE 0x56494126
53#define VIAFB_SET_VIDEO_DEVICE 0x56494127
54#define VIAFB_GET_VIDEO_DEVICE 0x56494128
55#define VIAFB_SET_SECOND_MODE 0x56494129
56#define VIAFB_SYNC_SURFACE 0x56494130
57#define VIAFB_GET_DRIVER_CAPS 0x56494131
58#define VIAFB_GET_IGA_SCALING_INFO 0x56494132
59#define VIAFB_GET_PANEL_MAX_SIZE 0x56494133
60#define VIAFB_GET_PANEL_MAX_POSITION 0x56494134
61#define VIAFB_SET_PANEL_SIZE 0x56494135
62#define VIAFB_SET_PANEL_POSITION 0x56494136
63#define VIAFB_GET_PANEL_POSITION 0x56494137
64#define VIAFB_GET_PANEL_SIZE 0x56494138
65
66#define None_Device 0x00
67#define CRT_Device 0x01
68#define LCD_Device 0x02
69#define DVI_Device 0x08
70#define CRT2_Device 0x10
71#define LCD2_Device 0x40
72
73#define OP_LCD_CENTERING 0x01
74#define OP_LCD_PANEL_ID 0x02
75#define OP_LCD_MODE 0x03
76
77/*SAMM operation flag*/
78#define OP_SAMM 0x80
79
80#define LCD_PANEL_ID_MAXIMUM 22
81
82#define STATE_ON 0x1
83#define STATE_OFF 0x0
84#define STATE_DEFAULT 0xFFFF
85
86#define MAX_ACTIVE_DEV_NUM 2
87
88struct device_t {
89 unsigned short crt:1;
90 unsigned short dvi:1;
91 unsigned short lcd:1;
92 unsigned short samm:1;
93 unsigned short lcd_dsp_cent:1;
94 unsigned char lcd_mode:1;
95 unsigned short epia_dvi:1;
96 unsigned short lcd_dual_edge:1;
97 unsigned short lcd2:1;
98
99 unsigned short primary_dev;
100 unsigned char lcd_panel_id;
101 unsigned short xres, yres;
102 unsigned short xres1, yres1;
103 unsigned short refresh;
104 unsigned short bpp;
105 unsigned short refresh1;
106 unsigned short bpp1;
107 unsigned short sequence;
108 unsigned short bus_width;
109};
110
111struct viafb_ioctl_info {
112 u32 viafb_id; /* for identifying viafb */
113#define VIAID 0x56494146 /* Identify myself with 'VIAF' */
114 u16 vendor_id;
115 u16 device_id;
116 u8 version;
117 u8 revision;
118 u8 reserved[246]; /* for future use */
119};
120
121struct viafb_ioctl_mode {
122 u32 xres;
123 u32 yres;
124 u32 refresh;
125 u32 bpp;
126 u32 xres_sec;
127 u32 yres_sec;
128 u32 virtual_xres_sec;
129 u32 virtual_yres_sec;
130 u32 refresh_sec;
131 u32 bpp_sec;
132};
133struct viafb_ioctl_samm {
134 u32 samm_status;
135 u32 size_prim;
136 u32 size_sec;
137 u32 mem_base;
138 u32 offset_sec;
139};
140
141struct viafb_driver_version {
142 int iMajorNum;
143 int iKernelNum;
144 int iOSNum;
145 int iMinorNum;
146};
147
148struct viafb_ioctl_lcd_attribute {
149 unsigned int panel_id;
150 unsigned int display_center;
151 unsigned int lcd_mode;
152};
153
154struct viafb_ioctl_setting {
155 /* Enable or disable active devices */
156 unsigned short device_flag;
157 /* Indicate which device should be turn on or turn off. */
158 unsigned short device_status;
159 unsigned int reserved;
160 /* Indicate which LCD's attribute can be changed. */
161 unsigned short lcd_operation_flag;
162 /* 1: SAMM ON 0: SAMM OFF */
163 unsigned short samm_status;
164 /* horizontal resolution of first device */
165 unsigned short first_dev_hor_res;
166 /* vertical resolution of first device */
167 unsigned short first_dev_ver_res;
168 /* horizontal resolution of second device */
169 unsigned short second_dev_hor_res;
170 /* vertical resolution of second device */
171 unsigned short second_dev_ver_res;
172 /* refresh rate of first device */
173 unsigned short first_dev_refresh;
174 /* bpp of first device */
175 unsigned short first_dev_bpp;
176 /* refresh rate of second device */
177 unsigned short second_dev_refresh;
178 /* bpp of second device */
179 unsigned short second_dev_bpp;
180 /* Indicate which device are primary display device. */
181 unsigned int primary_device;
182 /* Indicate which device will show video. only valid in duoview mode */
183 unsigned int video_device_status;
184 unsigned int struct_reserved[34];
185 struct viafb_ioctl_lcd_attribute lcd_attributes;
186};
187
188struct _UTFunctionCaps {
189 unsigned int dw3DScalingState;
190 unsigned int reserved[31];
191};
192
193struct _POSITIONVALUE {
194 unsigned int dwX;
195 unsigned int dwY;
196};
197
198struct _panel_size_pos_info {
199 unsigned int device_type;
200 int x;
201 int y;
202};
203
204extern int viafb_LCD_ON;
205extern int viafb_DVI_ON;
206
207int viafb_ioctl_get_viafb_info(u_long arg);
208int viafb_ioctl_hotplug(int hres, int vres, int bpp);
209
210#endif /* __IOCTL_H__ */
diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c
new file mode 100644
index 000000000000..6c7290a6a447
--- /dev/null
+++ b/drivers/video/via/lcd.c
@@ -0,0 +1,1821 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
14 * for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22#include "global.h"
23#include "lcdtbl.h"
24
25static struct iga2_shadow_crtc_timing iga2_shadow_crtc_reg = {
26 /* IGA2 Shadow Horizontal Total */
27 {IGA2_SHADOW_HOR_TOTAL_REG_NUM, {{CR6D, 0, 7}, {CR71, 3, 3} } },
28 /* IGA2 Shadow Horizontal Blank End */
29 {IGA2_SHADOW_HOR_BLANK_END_REG_NUM, {{CR6E, 0, 7} } },
30 /* IGA2 Shadow Vertical Total */
31 {IGA2_SHADOW_VER_TOTAL_REG_NUM, {{CR6F, 0, 7}, {CR71, 0, 2} } },
32 /* IGA2 Shadow Vertical Addressable Video */
33 {IGA2_SHADOW_VER_ADDR_REG_NUM, {{CR70, 0, 7}, {CR71, 4, 6} } },
34 /* IGA2 Shadow Vertical Blank Start */
35 {IGA2_SHADOW_VER_BLANK_START_REG_NUM,
36 {{CR72, 0, 7}, {CR74, 4, 6} } },
37 /* IGA2 Shadow Vertical Blank End */
38 {IGA2_SHADOW_VER_BLANK_END_REG_NUM, {{CR73, 0, 7}, {CR74, 0, 2} } },
39 /* IGA2 Shadow Vertical Sync Start */
40 {IGA2_SHADOW_VER_SYNC_START_REG_NUM, {{CR75, 0, 7}, {CR76, 4, 6} } },
41 /* IGA2 Shadow Vertical Sync End */
42 {IGA2_SHADOW_VER_SYNC_END_REG_NUM, {{CR76, 0, 3} } }
43};
44
45static struct _lcd_scaling_factor lcd_scaling_factor = {
46 /* LCD Horizontal Scaling Factor Register */
47 {LCD_HOR_SCALING_FACTOR_REG_NUM,
48 {{CR9F, 0, 1}, {CR77, 0, 7}, {CR79, 4, 5} } },
49 /* LCD Vertical Scaling Factor Register */
50 {LCD_VER_SCALING_FACTOR_REG_NUM,
51 {{CR79, 3, 3}, {CR78, 0, 7}, {CR79, 6, 7} } }
52};
53static struct _lcd_scaling_factor lcd_scaling_factor_CLE = {
54 /* LCD Horizontal Scaling Factor Register */
55 {LCD_HOR_SCALING_FACTOR_REG_NUM_CLE, {{CR77, 0, 7}, {CR79, 4, 5} } },
56 /* LCD Vertical Scaling Factor Register */
57 {LCD_VER_SCALING_FACTOR_REG_NUM_CLE, {{CR78, 0, 7}, {CR79, 6, 7} } }
58};
59
60static int check_lvds_chip(int device_id_subaddr, int device_id);
61static bool lvds_identify_integratedlvds(void);
62static int fp_id_to_vindex(int panel_id);
63static int lvds_register_read(int index);
64static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
65 int panel_vres);
66static void load_lcd_k400_patch_tbl(int set_hres, int set_vres,
67 int panel_id);
68static void load_lcd_p880_patch_tbl(int set_hres, int set_vres,
69 int panel_id);
70static void load_lcd_patch_regs(int set_hres, int set_vres,
71 int panel_id, int set_iga);
72static void via_pitch_alignment_patch_lcd(
73 struct lvds_setting_information *plvds_setting_info,
74 struct lvds_chip_information
75 *plvds_chip_info);
76static void lcd_patch_skew_dvp0(struct lvds_setting_information
77 *plvds_setting_info,
78 struct lvds_chip_information *plvds_chip_info);
79static void lcd_patch_skew_dvp1(struct lvds_setting_information
80 *plvds_setting_info,
81 struct lvds_chip_information *plvds_chip_info);
82static void lcd_patch_skew(struct lvds_setting_information
83 *plvds_setting_info, struct lvds_chip_information *plvds_chip_info);
84
85static void integrated_lvds_disable(struct lvds_setting_information
86 *plvds_setting_info,
87 struct lvds_chip_information *plvds_chip_info);
88static void integrated_lvds_enable(struct lvds_setting_information
89 *plvds_setting_info,
90 struct lvds_chip_information *plvds_chip_info);
91static void lcd_powersequence_off(void);
92static void lcd_powersequence_on(void);
93static void fill_lcd_format(void);
94static void check_diport_of_integrated_lvds(
95 struct lvds_chip_information *plvds_chip_info,
96 struct lvds_setting_information
97 *plvds_setting_info);
98static struct display_timing lcd_centering_timging(struct display_timing
99 mode_crt_reg,
100 struct display_timing panel_crt_reg);
101static void load_crtc_shadow_timing(struct display_timing mode_timing,
102 struct display_timing panel_timing);
103static void viafb_load_scaling_factor_for_p4m900(int set_hres,
104 int set_vres, int panel_hres, int panel_vres);
105
106static int check_lvds_chip(int device_id_subaddr, int device_id)
107{
108 if (lvds_register_read(device_id_subaddr) == device_id)
109 return OK;
110 else
111 return FAIL;
112}
113
114void viafb_init_lcd_size(void)
115{
116 DEBUG_MSG(KERN_INFO "viafb_init_lcd_size()\n");
117 DEBUG_MSG(KERN_INFO
118 "viaparinfo->lvds_setting_info->get_lcd_size_method %d\n",
119 viaparinfo->lvds_setting_info->get_lcd_size_method);
120
121 switch (viaparinfo->lvds_setting_info->get_lcd_size_method) {
122 case GET_LCD_SIZE_BY_SYSTEM_BIOS:
123 break;
124 case GET_LCD_SZIE_BY_HW_STRAPPING:
125 break;
126 case GET_LCD_SIZE_BY_VGA_BIOS:
127 DEBUG_MSG(KERN_INFO "Get LCD Size method by VGA BIOS !!\n");
128 viaparinfo->lvds_setting_info->lcd_panel_size =
129 fp_id_to_vindex(viafb_lcd_panel_id);
130 DEBUG_MSG(KERN_INFO "LCD Panel_ID = %d\n",
131 viaparinfo->lvds_setting_info->lcd_panel_id);
132 DEBUG_MSG(KERN_INFO "LCD Panel Size = %d\n",
133 viaparinfo->lvds_setting_info->lcd_panel_size);
134 break;
135 case GET_LCD_SIZE_BY_USER_SETTING:
136 DEBUG_MSG(KERN_INFO "Get LCD Size method by user setting !!\n");
137 viaparinfo->lvds_setting_info->lcd_panel_size =
138 fp_id_to_vindex(viafb_lcd_panel_id);
139 DEBUG_MSG(KERN_INFO "LCD Panel_ID = %d\n",
140 viaparinfo->lvds_setting_info->lcd_panel_id);
141 DEBUG_MSG(KERN_INFO "LCD Panel Size = %d\n",
142 viaparinfo->lvds_setting_info->lcd_panel_size);
143 break;
144 default:
145 DEBUG_MSG(KERN_INFO "viafb_init_lcd_size fail\n");
146 viaparinfo->lvds_setting_info->lcd_panel_id =
147 LCD_PANEL_ID1_800X600;
148 viaparinfo->lvds_setting_info->lcd_panel_size =
149 fp_id_to_vindex(LCD_PANEL_ID1_800X600);
150 }
151 viaparinfo->lvds_setting_info2->lcd_panel_id =
152 viaparinfo->lvds_setting_info->lcd_panel_id;
153 viaparinfo->lvds_setting_info2->lcd_panel_size =
154 viaparinfo->lvds_setting_info->lcd_panel_size;
155 viaparinfo->lvds_setting_info2->lcd_panel_hres =
156 viaparinfo->lvds_setting_info->lcd_panel_hres;
157 viaparinfo->lvds_setting_info2->lcd_panel_vres =
158 viaparinfo->lvds_setting_info->lcd_panel_vres;
159 viaparinfo->lvds_setting_info2->device_lcd_dualedge =
160 viaparinfo->lvds_setting_info->device_lcd_dualedge;
161 viaparinfo->lvds_setting_info2->LCDDithering =
162 viaparinfo->lvds_setting_info->LCDDithering;
163}
164
165static bool lvds_identify_integratedlvds(void)
166{
167 if (viafb_display_hardware_layout == HW_LAYOUT_LCD_EXTERNAL_LCD2) {
168 /* Two dual channel LCD (Internal LVDS + External LVDS): */
169 /* If we have an external LVDS, such as VT1636, we should
170 have its chip ID already. */
171 if (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
172 viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name =
173 INTEGRATED_LVDS;
174 DEBUG_MSG(KERN_INFO "Support two dual channel LVDS!\
175 (Internal LVDS + External LVDS)\n");
176 } else {
177 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
178 INTEGRATED_LVDS;
179 DEBUG_MSG(KERN_INFO "Not found external LVDS,\
180 so can't support two dual channel LVDS!\n");
181 }
182 } else if (viafb_display_hardware_layout == HW_LAYOUT_LCD1_LCD2) {
183 /* Two single channel LCD (Internal LVDS + Internal LVDS): */
184 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
185 INTEGRATED_LVDS;
186 viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name =
187 INTEGRATED_LVDS;
188 DEBUG_MSG(KERN_INFO "Support two single channel LVDS!\
189 (Internal LVDS + Internal LVDS)\n");
190 } else if (viafb_display_hardware_layout != HW_LAYOUT_DVI_ONLY) {
191 /* If we have found external LVDS, just use it,
192 otherwise, we will use internal LVDS as default. */
193 if (!viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
194 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
195 INTEGRATED_LVDS;
196 DEBUG_MSG(KERN_INFO "Found Integrated LVDS!\n");
197 }
198 } else {
199 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
200 NON_LVDS_TRANSMITTER;
201 DEBUG_MSG(KERN_INFO "Do not support LVDS!\n");
202 return false;
203 }
204
205 return true;
206}
207
208int viafb_lvds_trasmitter_identify(void)
209{
210 viaparinfo->i2c_stuff.i2c_port = I2CPORTINDEX;
211 if (viafb_lvds_identify_vt1636()) {
212 viaparinfo->chip_info->lvds_chip_info.i2c_port = I2CPORTINDEX;
213 DEBUG_MSG(KERN_INFO
214 "Found VIA VT1636 LVDS on port i2c 0x31 \n");
215 } else {
216 viaparinfo->i2c_stuff.i2c_port = GPIOPORTINDEX;
217 if (viafb_lvds_identify_vt1636()) {
218 viaparinfo->chip_info->lvds_chip_info.i2c_port =
219 GPIOPORTINDEX;
220 DEBUG_MSG(KERN_INFO
221 "Found VIA VT1636 LVDS on port gpio 0x2c \n");
222 }
223 }
224
225 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700)
226 lvds_identify_integratedlvds();
227
228 if (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name)
229 return true;
230 /* Check for VT1631: */
231 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = VT1631_LVDS;
232 viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr =
233 VT1631_LVDS_I2C_ADDR;
234
235 if (check_lvds_chip(VT1631_DEVICE_ID_REG, VT1631_DEVICE_ID) != FAIL) {
236 DEBUG_MSG(KERN_INFO "\n VT1631 LVDS ! \n");
237 DEBUG_MSG(KERN_INFO "\n %2d",
238 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name);
239 DEBUG_MSG(KERN_INFO "\n %2d",
240 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name);
241 return OK;
242 }
243
244 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
245 NON_LVDS_TRANSMITTER;
246 viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr =
247 VT1631_LVDS_I2C_ADDR;
248 return FAIL;
249}
250
251static int fp_id_to_vindex(int panel_id)
252{
253 DEBUG_MSG(KERN_INFO "fp_get_panel_id()\n");
254
255 if (panel_id > LCD_PANEL_ID_MAXIMUM)
256 viafb_lcd_panel_id = panel_id =
257 viafb_read_reg(VIACR, CR3F) & 0x0F;
258
259 switch (panel_id) {
260 case 0x0:
261 viaparinfo->lvds_setting_info->lcd_panel_hres = 640;
262 viaparinfo->lvds_setting_info->lcd_panel_vres = 480;
263 viaparinfo->lvds_setting_info->lcd_panel_id =
264 LCD_PANEL_ID0_640X480;
265 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
266 viaparinfo->lvds_setting_info->LCDDithering = 1;
267 return VIA_RES_640X480;
268 break;
269 case 0x1:
270 viaparinfo->lvds_setting_info->lcd_panel_hres = 800;
271 viaparinfo->lvds_setting_info->lcd_panel_vres = 600;
272 viaparinfo->lvds_setting_info->lcd_panel_id =
273 LCD_PANEL_ID1_800X600;
274 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
275 viaparinfo->lvds_setting_info->LCDDithering = 1;
276 return VIA_RES_800X600;
277 break;
278 case 0x2:
279 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
280 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
281 viaparinfo->lvds_setting_info->lcd_panel_id =
282 LCD_PANEL_ID2_1024X768;
283 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
284 viaparinfo->lvds_setting_info->LCDDithering = 1;
285 return VIA_RES_1024X768;
286 break;
287 case 0x3:
288 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
289 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
290 viaparinfo->lvds_setting_info->lcd_panel_id =
291 LCD_PANEL_ID3_1280X768;
292 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
293 viaparinfo->lvds_setting_info->LCDDithering = 1;
294 return VIA_RES_1280X768;
295 break;
296 case 0x4:
297 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
298 viaparinfo->lvds_setting_info->lcd_panel_vres = 1024;
299 viaparinfo->lvds_setting_info->lcd_panel_id =
300 LCD_PANEL_ID4_1280X1024;
301 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
302 viaparinfo->lvds_setting_info->LCDDithering = 1;
303 return VIA_RES_1280X1024;
304 break;
305 case 0x5:
306 viaparinfo->lvds_setting_info->lcd_panel_hres = 1400;
307 viaparinfo->lvds_setting_info->lcd_panel_vres = 1050;
308 viaparinfo->lvds_setting_info->lcd_panel_id =
309 LCD_PANEL_ID5_1400X1050;
310 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
311 viaparinfo->lvds_setting_info->LCDDithering = 1;
312 return VIA_RES_1400X1050;
313 break;
314 case 0x6:
315 viaparinfo->lvds_setting_info->lcd_panel_hres = 1600;
316 viaparinfo->lvds_setting_info->lcd_panel_vres = 1200;
317 viaparinfo->lvds_setting_info->lcd_panel_id =
318 LCD_PANEL_ID6_1600X1200;
319 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
320 viaparinfo->lvds_setting_info->LCDDithering = 1;
321 return VIA_RES_1600X1200;
322 break;
323 case 0x8:
324 viaparinfo->lvds_setting_info->lcd_panel_hres = 800;
325 viaparinfo->lvds_setting_info->lcd_panel_vres = 480;
326 viaparinfo->lvds_setting_info->lcd_panel_id =
327 LCD_PANEL_IDA_800X480;
328 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
329 viaparinfo->lvds_setting_info->LCDDithering = 1;
330 return VIA_RES_800X480;
331 break;
332 case 0x9:
333 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
334 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
335 viaparinfo->lvds_setting_info->lcd_panel_id =
336 LCD_PANEL_ID2_1024X768;
337 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
338 viaparinfo->lvds_setting_info->LCDDithering = 1;
339 return VIA_RES_1024X768;
340 break;
341 case 0xA:
342 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
343 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
344 viaparinfo->lvds_setting_info->lcd_panel_id =
345 LCD_PANEL_ID2_1024X768;
346 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
347 viaparinfo->lvds_setting_info->LCDDithering = 0;
348 return VIA_RES_1024X768;
349 break;
350 case 0xB:
351 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
352 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
353 viaparinfo->lvds_setting_info->lcd_panel_id =
354 LCD_PANEL_ID2_1024X768;
355 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
356 viaparinfo->lvds_setting_info->LCDDithering = 0;
357 return VIA_RES_1024X768;
358 break;
359 case 0xC:
360 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
361 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
362 viaparinfo->lvds_setting_info->lcd_panel_id =
363 LCD_PANEL_ID3_1280X768;
364 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
365 viaparinfo->lvds_setting_info->LCDDithering = 0;
366 return VIA_RES_1280X768;
367 break;
368 case 0xD:
369 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
370 viaparinfo->lvds_setting_info->lcd_panel_vres = 1024;
371 viaparinfo->lvds_setting_info->lcd_panel_id =
372 LCD_PANEL_ID4_1280X1024;
373 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
374 viaparinfo->lvds_setting_info->LCDDithering = 0;
375 return VIA_RES_1280X1024;
376 break;
377 case 0xE:
378 viaparinfo->lvds_setting_info->lcd_panel_hres = 1400;
379 viaparinfo->lvds_setting_info->lcd_panel_vres = 1050;
380 viaparinfo->lvds_setting_info->lcd_panel_id =
381 LCD_PANEL_ID5_1400X1050;
382 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
383 viaparinfo->lvds_setting_info->LCDDithering = 0;
384 return VIA_RES_1400X1050;
385 break;
386 case 0xF:
387 viaparinfo->lvds_setting_info->lcd_panel_hres = 1600;
388 viaparinfo->lvds_setting_info->lcd_panel_vres = 1200;
389 viaparinfo->lvds_setting_info->lcd_panel_id =
390 LCD_PANEL_ID6_1600X1200;
391 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
392 viaparinfo->lvds_setting_info->LCDDithering = 0;
393 return VIA_RES_1600X1200;
394 break;
395 case 0x10:
396 viaparinfo->lvds_setting_info->lcd_panel_hres = 1366;
397 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
398 viaparinfo->lvds_setting_info->lcd_panel_id =
399 LCD_PANEL_ID7_1366X768;
400 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
401 viaparinfo->lvds_setting_info->LCDDithering = 0;
402 return VIA_RES_1368X768;
403 break;
404 case 0x11:
405 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
406 viaparinfo->lvds_setting_info->lcd_panel_vres = 600;
407 viaparinfo->lvds_setting_info->lcd_panel_id =
408 LCD_PANEL_ID8_1024X600;
409 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
410 viaparinfo->lvds_setting_info->LCDDithering = 1;
411 return VIA_RES_1024X600;
412 break;
413 case 0x12:
414 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
415 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
416 viaparinfo->lvds_setting_info->lcd_panel_id =
417 LCD_PANEL_ID3_1280X768;
418 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
419 viaparinfo->lvds_setting_info->LCDDithering = 1;
420 return VIA_RES_1280X768;
421 break;
422 case 0x13:
423 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
424 viaparinfo->lvds_setting_info->lcd_panel_vres = 800;
425 viaparinfo->lvds_setting_info->lcd_panel_id =
426 LCD_PANEL_ID9_1280X800;
427 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
428 viaparinfo->lvds_setting_info->LCDDithering = 1;
429 return VIA_RES_1280X800;
430 break;
431 case 0x14:
432 viaparinfo->lvds_setting_info->lcd_panel_hres = 1360;
433 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
434 viaparinfo->lvds_setting_info->lcd_panel_id =
435 LCD_PANEL_IDB_1360X768;
436 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
437 viaparinfo->lvds_setting_info->LCDDithering = 0;
438 return VIA_RES_1360X768;
439 break;
440 case 0x15:
441 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
442 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
443 viaparinfo->lvds_setting_info->lcd_panel_id =
444 LCD_PANEL_ID3_1280X768;
445 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
446 viaparinfo->lvds_setting_info->LCDDithering = 0;
447 return VIA_RES_1280X768;
448 break;
449 case 0x16:
450 viaparinfo->lvds_setting_info->lcd_panel_hres = 480;
451 viaparinfo->lvds_setting_info->lcd_panel_vres = 640;
452 viaparinfo->lvds_setting_info->lcd_panel_id =
453 LCD_PANEL_IDC_480X640;
454 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
455 viaparinfo->lvds_setting_info->LCDDithering = 1;
456 return VIA_RES_480X640;
457 break;
458 default:
459 viaparinfo->lvds_setting_info->lcd_panel_hres = 800;
460 viaparinfo->lvds_setting_info->lcd_panel_vres = 600;
461 viaparinfo->lvds_setting_info->lcd_panel_id =
462 LCD_PANEL_ID1_800X600;
463 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
464 viaparinfo->lvds_setting_info->LCDDithering = 1;
465 return VIA_RES_800X600;
466 }
467}
468
469static int lvds_register_read(int index)
470{
471 u8 data;
472
473 viaparinfo->i2c_stuff.i2c_port = GPIOPORTINDEX;
474 viafb_i2c_readbyte((u8) viaparinfo->chip_info->
475 lvds_chip_info.lvds_chip_slave_addr,
476 (u8) index, &data);
477 return data;
478}
479
480static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
481 int panel_vres)
482{
483 int reg_value = 0;
484 int viafb_load_reg_num;
485 struct io_register *reg = NULL;
486
487 DEBUG_MSG(KERN_INFO "load_lcd_scaling()!!\n");
488
489 /* LCD Scaling Enable */
490 viafb_write_reg_mask(CR79, VIACR, 0x07, BIT0 + BIT1 + BIT2);
491 if (UNICHROME_P4M900 == viaparinfo->chip_info->gfx_chip_name) {
492 viafb_load_scaling_factor_for_p4m900(set_hres, set_vres,
493 panel_hres, panel_vres);
494 return;
495 }
496
497 /* Check if expansion for horizontal */
498 if (set_hres != panel_hres) {
499 /* Load Horizontal Scaling Factor */
500 switch (viaparinfo->chip_info->gfx_chip_name) {
501 case UNICHROME_CLE266:
502 case UNICHROME_K400:
503 reg_value =
504 CLE266_LCD_HOR_SCF_FORMULA(set_hres, panel_hres);
505 viafb_load_reg_num =
506 lcd_scaling_factor_CLE.lcd_hor_scaling_factor.
507 reg_num;
508 reg = lcd_scaling_factor_CLE.lcd_hor_scaling_factor.reg;
509 viafb_load_reg(reg_value,
510 viafb_load_reg_num, reg, VIACR);
511 break;
512 case UNICHROME_K800:
513 case UNICHROME_PM800:
514 case UNICHROME_CN700:
515 case UNICHROME_CX700:
516 case UNICHROME_K8M890:
517 case UNICHROME_P4M890:
518 reg_value =
519 K800_LCD_HOR_SCF_FORMULA(set_hres, panel_hres);
520 /* Horizontal scaling enabled */
521 viafb_write_reg_mask(CRA2, VIACR, 0xC0, BIT7 + BIT6);
522 viafb_load_reg_num =
523 lcd_scaling_factor.lcd_hor_scaling_factor.reg_num;
524 reg = lcd_scaling_factor.lcd_hor_scaling_factor.reg;
525 viafb_load_reg(reg_value,
526 viafb_load_reg_num, reg, VIACR);
527 break;
528 }
529
530 DEBUG_MSG(KERN_INFO "Horizontal Scaling value = %d", reg_value);
531 } else {
532 /* Horizontal scaling disabled */
533 viafb_write_reg_mask(CRA2, VIACR, 0x00, BIT7);
534 }
535
536 /* Check if expansion for vertical */
537 if (set_vres != panel_vres) {
538 /* Load Vertical Scaling Factor */
539 switch (viaparinfo->chip_info->gfx_chip_name) {
540 case UNICHROME_CLE266:
541 case UNICHROME_K400:
542 reg_value =
543 CLE266_LCD_VER_SCF_FORMULA(set_vres, panel_vres);
544 viafb_load_reg_num =
545 lcd_scaling_factor_CLE.lcd_ver_scaling_factor.
546 reg_num;
547 reg = lcd_scaling_factor_CLE.lcd_ver_scaling_factor.reg;
548 viafb_load_reg(reg_value,
549 viafb_load_reg_num, reg, VIACR);
550 break;
551 case UNICHROME_K800:
552 case UNICHROME_PM800:
553 case UNICHROME_CN700:
554 case UNICHROME_CX700:
555 case UNICHROME_K8M890:
556 case UNICHROME_P4M890:
557 reg_value =
558 K800_LCD_VER_SCF_FORMULA(set_vres, panel_vres);
559 /* Vertical scaling enabled */
560 viafb_write_reg_mask(CRA2, VIACR, 0x08, BIT3);
561 viafb_load_reg_num =
562 lcd_scaling_factor.lcd_ver_scaling_factor.reg_num;
563 reg = lcd_scaling_factor.lcd_ver_scaling_factor.reg;
564 viafb_load_reg(reg_value,
565 viafb_load_reg_num, reg, VIACR);
566 break;
567 }
568
569 DEBUG_MSG(KERN_INFO "Vertical Scaling value = %d", reg_value);
570 } else {
571 /* Vertical scaling disabled */
572 viafb_write_reg_mask(CRA2, VIACR, 0x00, BIT3);
573 }
574}
575
576static void load_lcd_k400_patch_tbl(int set_hres, int set_vres,
577 int panel_id)
578{
579 int vmode_index;
580 int reg_num = 0;
581 struct io_reg *lcd_patch_reg = NULL;
582
583 if (viaparinfo->lvds_setting_info->iga_path == IGA2)
584 vmode_index = viafb_get_mode_index(set_hres, set_vres, 1);
585 else
586 vmode_index = viafb_get_mode_index(set_hres, set_vres, 0);
587 switch (panel_id) {
588 /* LCD 800x600 */
589 case LCD_PANEL_ID1_800X600:
590 switch (vmode_index) {
591 case VIA_RES_640X400:
592 case VIA_RES_640X480:
593 reg_num = NUM_TOTAL_K400_LCD_RES_6X4_8X6;
594 lcd_patch_reg = K400_LCD_RES_6X4_8X6;
595 break;
596 case VIA_RES_720X480:
597 case VIA_RES_720X576:
598 reg_num = NUM_TOTAL_K400_LCD_RES_7X4_8X6;
599 lcd_patch_reg = K400_LCD_RES_7X4_8X6;
600 break;
601 }
602 break;
603
604 /* LCD 1024x768 */
605 case LCD_PANEL_ID2_1024X768:
606 switch (vmode_index) {
607 case VIA_RES_640X400:
608 case VIA_RES_640X480:
609 reg_num = NUM_TOTAL_K400_LCD_RES_6X4_10X7;
610 lcd_patch_reg = K400_LCD_RES_6X4_10X7;
611 break;
612 case VIA_RES_720X480:
613 case VIA_RES_720X576:
614 reg_num = NUM_TOTAL_K400_LCD_RES_7X4_10X7;
615 lcd_patch_reg = K400_LCD_RES_7X4_10X7;
616 break;
617 case VIA_RES_800X600:
618 reg_num = NUM_TOTAL_K400_LCD_RES_8X6_10X7;
619 lcd_patch_reg = K400_LCD_RES_8X6_10X7;
620 break;
621 }
622 break;
623
624 /* LCD 1280x1024 */
625 case LCD_PANEL_ID4_1280X1024:
626 switch (vmode_index) {
627 case VIA_RES_640X400:
628 case VIA_RES_640X480:
629 reg_num = NUM_TOTAL_K400_LCD_RES_6X4_12X10;
630 lcd_patch_reg = K400_LCD_RES_6X4_12X10;
631 break;
632 case VIA_RES_720X480:
633 case VIA_RES_720X576:
634 reg_num = NUM_TOTAL_K400_LCD_RES_7X4_12X10;
635 lcd_patch_reg = K400_LCD_RES_7X4_12X10;
636 break;
637 case VIA_RES_800X600:
638 reg_num = NUM_TOTAL_K400_LCD_RES_8X6_12X10;
639 lcd_patch_reg = K400_LCD_RES_8X6_12X10;
640 break;
641 case VIA_RES_1024X768:
642 reg_num = NUM_TOTAL_K400_LCD_RES_10X7_12X10;
643 lcd_patch_reg = K400_LCD_RES_10X7_12X10;
644 break;
645
646 }
647 break;
648
649 /* LCD 1400x1050 */
650 case LCD_PANEL_ID5_1400X1050:
651 switch (vmode_index) {
652 case VIA_RES_640X480:
653 reg_num = NUM_TOTAL_K400_LCD_RES_6X4_14X10;
654 lcd_patch_reg = K400_LCD_RES_6X4_14X10;
655 break;
656 case VIA_RES_800X600:
657 reg_num = NUM_TOTAL_K400_LCD_RES_8X6_14X10;
658 lcd_patch_reg = K400_LCD_RES_8X6_14X10;
659 break;
660 case VIA_RES_1024X768:
661 reg_num = NUM_TOTAL_K400_LCD_RES_10X7_14X10;
662 lcd_patch_reg = K400_LCD_RES_10X7_14X10;
663 break;
664 case VIA_RES_1280X768:
665 case VIA_RES_1280X800:
666 case VIA_RES_1280X960:
667 case VIA_RES_1280X1024:
668 reg_num = NUM_TOTAL_K400_LCD_RES_12X10_14X10;
669 lcd_patch_reg = K400_LCD_RES_12X10_14X10;
670 break;
671 }
672 break;
673
674 /* LCD 1600x1200 */
675 case LCD_PANEL_ID6_1600X1200:
676 switch (vmode_index) {
677 case VIA_RES_640X400:
678 case VIA_RES_640X480:
679 reg_num = NUM_TOTAL_K400_LCD_RES_6X4_16X12;
680 lcd_patch_reg = K400_LCD_RES_6X4_16X12;
681 break;
682 case VIA_RES_720X480:
683 case VIA_RES_720X576:
684 reg_num = NUM_TOTAL_K400_LCD_RES_7X4_16X12;
685 lcd_patch_reg = K400_LCD_RES_7X4_16X12;
686 break;
687 case VIA_RES_800X600:
688 reg_num = NUM_TOTAL_K400_LCD_RES_8X6_16X12;
689 lcd_patch_reg = K400_LCD_RES_8X6_16X12;
690 break;
691 case VIA_RES_1024X768:
692 reg_num = NUM_TOTAL_K400_LCD_RES_10X7_16X12;
693 lcd_patch_reg = K400_LCD_RES_10X7_16X12;
694 break;
695 case VIA_RES_1280X768:
696 case VIA_RES_1280X800:
697 case VIA_RES_1280X960:
698 case VIA_RES_1280X1024:
699 reg_num = NUM_TOTAL_K400_LCD_RES_12X10_16X12;
700 lcd_patch_reg = K400_LCD_RES_12X10_16X12;
701 break;
702 }
703 break;
704
705 /* LCD 1366x768 */
706 case LCD_PANEL_ID7_1366X768:
707 switch (vmode_index) {
708 case VIA_RES_640X480:
709 reg_num = NUM_TOTAL_K400_LCD_RES_6X4_1366X7;
710 lcd_patch_reg = K400_LCD_RES_6X4_1366X7;
711 break;
712 case VIA_RES_720X480:
713 case VIA_RES_720X576:
714 reg_num = NUM_TOTAL_K400_LCD_RES_7X4_1366X7;
715 lcd_patch_reg = K400_LCD_RES_7X4_1366X7;
716 break;
717 case VIA_RES_800X600:
718 reg_num = NUM_TOTAL_K400_LCD_RES_8X6_1366X7;
719 lcd_patch_reg = K400_LCD_RES_8X6_1366X7;
720 break;
721 case VIA_RES_1024X768:
722 reg_num = NUM_TOTAL_K400_LCD_RES_10X7_1366X7;
723 lcd_patch_reg = K400_LCD_RES_10X7_1366X7;
724 break;
725 case VIA_RES_1280X768:
726 case VIA_RES_1280X800:
727 case VIA_RES_1280X960:
728 case VIA_RES_1280X1024:
729 reg_num = NUM_TOTAL_K400_LCD_RES_12X10_1366X7;
730 lcd_patch_reg = K400_LCD_RES_12X10_1366X7;
731 break;
732 }
733 break;
734
735 /* LCD 1360x768 */
736 case LCD_PANEL_IDB_1360X768:
737 break;
738 }
739 if (reg_num != 0) {
740 /* H.W. Reset : ON */
741 viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
742
743 viafb_write_regx(lcd_patch_reg, reg_num);
744
745 /* H.W. Reset : OFF */
746 viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
747
748 /* Reset PLL */
749 viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1);
750 viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1);
751
752 /* Fire! */
753 outb(inb(VIARMisc) | (BIT2 + BIT3), VIAWMisc);
754 }
755}
756
757static void load_lcd_p880_patch_tbl(int set_hres, int set_vres,
758 int panel_id)
759{
760 int vmode_index;
761 int reg_num = 0;
762 struct io_reg *lcd_patch_reg = NULL;
763
764 if (viaparinfo->lvds_setting_info->iga_path == IGA2)
765 vmode_index = viafb_get_mode_index(set_hres, set_vres, 1);
766 else
767 vmode_index = viafb_get_mode_index(set_hres, set_vres, 0);
768
769 switch (panel_id) {
770 case LCD_PANEL_ID5_1400X1050:
771 switch (vmode_index) {
772 case VIA_RES_640X480:
773 reg_num = NUM_TOTAL_P880_LCD_RES_6X4_14X10;
774 lcd_patch_reg = P880_LCD_RES_6X4_14X10;
775 break;
776 case VIA_RES_800X600:
777 reg_num = NUM_TOTAL_P880_LCD_RES_8X6_14X10;
778 lcd_patch_reg = P880_LCD_RES_8X6_14X10;
779 break;
780 }
781 break;
782 case LCD_PANEL_ID6_1600X1200:
783 switch (vmode_index) {
784 case VIA_RES_640X400:
785 case VIA_RES_640X480:
786 reg_num = NUM_TOTAL_P880_LCD_RES_6X4_16X12;
787 lcd_patch_reg = P880_LCD_RES_6X4_16X12;
788 break;
789 case VIA_RES_720X480:
790 case VIA_RES_720X576:
791 reg_num = NUM_TOTAL_P880_LCD_RES_7X4_16X12;
792 lcd_patch_reg = P880_LCD_RES_7X4_16X12;
793 break;
794 case VIA_RES_800X600:
795 reg_num = NUM_TOTAL_P880_LCD_RES_8X6_16X12;
796 lcd_patch_reg = P880_LCD_RES_8X6_16X12;
797 break;
798 case VIA_RES_1024X768:
799 reg_num = NUM_TOTAL_P880_LCD_RES_10X7_16X12;
800 lcd_patch_reg = P880_LCD_RES_10X7_16X12;
801 break;
802 case VIA_RES_1280X768:
803 case VIA_RES_1280X960:
804 case VIA_RES_1280X1024:
805 reg_num = NUM_TOTAL_P880_LCD_RES_12X10_16X12;
806 lcd_patch_reg = P880_LCD_RES_12X10_16X12;
807 break;
808 }
809 break;
810
811 }
812 if (reg_num != 0) {
813 /* H.W. Reset : ON */
814 viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
815
816 viafb_write_regx(lcd_patch_reg, reg_num);
817
818 /* H.W. Reset : OFF */
819 viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
820
821 /* Reset PLL */
822 viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1);
823 viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1);
824
825 /* Fire! */
826 outb(inb(VIARMisc) | (BIT2 + BIT3), VIAWMisc);
827 }
828}
829
830static void load_lcd_patch_regs(int set_hres, int set_vres,
831 int panel_id, int set_iga)
832{
833 int vmode_index;
834
835 if (viaparinfo->lvds_setting_info->iga_path == IGA2)
836 vmode_index = viafb_get_mode_index(set_hres, set_vres, 1);
837 else
838 vmode_index = viafb_get_mode_index(set_hres, set_vres, 0);
839
840 viafb_unlock_crt();
841
842 /* Patch for simultaneous & Expansion */
843 if ((set_iga == IGA1_IGA2) &&
844 (viaparinfo->lvds_setting_info->display_method ==
845 LCD_EXPANDSION)) {
846 switch (viaparinfo->chip_info->gfx_chip_name) {
847 case UNICHROME_CLE266:
848 case UNICHROME_K400:
849 load_lcd_k400_patch_tbl(set_hres, set_vres, panel_id);
850 break;
851 case UNICHROME_K800:
852 break;
853 case UNICHROME_PM800:
854 case UNICHROME_CN700:
855 case UNICHROME_CX700:
856 load_lcd_p880_patch_tbl(set_hres, set_vres, panel_id);
857 }
858 }
859
860 viafb_lock_crt();
861}
862
863static void via_pitch_alignment_patch_lcd(
864 struct lvds_setting_information *plvds_setting_info,
865 struct lvds_chip_information
866 *plvds_chip_info)
867{
868 unsigned char cr13, cr35, cr65, cr66, cr67;
869 unsigned long dwScreenPitch = 0;
870 unsigned long dwPitch;
871
872 dwPitch = plvds_setting_info->h_active * (plvds_setting_info->bpp >> 3);
873 if (dwPitch & 0x1F) {
874 dwScreenPitch = ((dwPitch + 31) & ~31) >> 3;
875 if (plvds_setting_info->iga_path == IGA2) {
876 if (plvds_setting_info->bpp > 8) {
877 cr66 = (unsigned char)(dwScreenPitch & 0xFF);
878 viafb_write_reg(CR66, VIACR, cr66);
879 cr67 = viafb_read_reg(VIACR, CR67) & 0xFC;
880 cr67 |=
881 (unsigned
882 char)((dwScreenPitch & 0x300) >> 8);
883 viafb_write_reg(CR67, VIACR, cr67);
884 }
885
886 /* Fetch Count */
887 cr67 = viafb_read_reg(VIACR, CR67) & 0xF3;
888 cr67 |= (unsigned char)((dwScreenPitch & 0x600) >> 7);
889 viafb_write_reg(CR67, VIACR, cr67);
890 cr65 = (unsigned char)((dwScreenPitch >> 1) & 0xFF);
891 cr65 += 2;
892 viafb_write_reg(CR65, VIACR, cr65);
893 } else {
894 if (plvds_setting_info->bpp > 8) {
895 cr13 = (unsigned char)(dwScreenPitch & 0xFF);
896 viafb_write_reg(CR13, VIACR, cr13);
897 cr35 = viafb_read_reg(VIACR, CR35) & 0x1F;
898 cr35 |=
899 (unsigned
900 char)((dwScreenPitch & 0x700) >> 3);
901 viafb_write_reg(CR35, VIACR, cr35);
902 }
903 }
904 }
905}
906static void lcd_patch_skew_dvp0(struct lvds_setting_information
907 *plvds_setting_info,
908 struct lvds_chip_information *plvds_chip_info)
909{
910 if (VT1636_LVDS == plvds_chip_info->lvds_chip_name) {
911 switch (viaparinfo->chip_info->gfx_chip_name) {
912 case UNICHROME_P4M900:
913 viafb_vt1636_patch_skew_on_vt3364(plvds_setting_info,
914 plvds_chip_info);
915 break;
916 case UNICHROME_P4M890:
917 viafb_vt1636_patch_skew_on_vt3327(plvds_setting_info,
918 plvds_chip_info);
919 break;
920 }
921 }
922}
923static void lcd_patch_skew_dvp1(struct lvds_setting_information
924 *plvds_setting_info,
925 struct lvds_chip_information *plvds_chip_info)
926{
927 if (VT1636_LVDS == plvds_chip_info->lvds_chip_name) {
928 switch (viaparinfo->chip_info->gfx_chip_name) {
929 case UNICHROME_CX700:
930 viafb_vt1636_patch_skew_on_vt3324(plvds_setting_info,
931 plvds_chip_info);
932 break;
933 }
934 }
935}
936static void lcd_patch_skew(struct lvds_setting_information
937 *plvds_setting_info, struct lvds_chip_information *plvds_chip_info)
938{
939 DEBUG_MSG(KERN_INFO "lcd_patch_skew\n");
940 switch (plvds_chip_info->output_interface) {
941 case INTERFACE_DVP0:
942 lcd_patch_skew_dvp0(plvds_setting_info, plvds_chip_info);
943 break;
944 case INTERFACE_DVP1:
945 lcd_patch_skew_dvp1(plvds_setting_info, plvds_chip_info);
946 break;
947 case INTERFACE_DFP_LOW:
948 if (UNICHROME_P4M900 == viaparinfo->chip_info->gfx_chip_name) {
949 viafb_write_reg_mask(CR99, VIACR, 0x08,
950 BIT0 + BIT1 + BIT2 + BIT3);
951 }
952 break;
953 }
954}
955
956/* LCD Set Mode */
957void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,
958 struct lvds_setting_information *plvds_setting_info,
959 struct lvds_chip_information *plvds_chip_info)
960{
961 int video_index = plvds_setting_info->lcd_panel_size;
962 int set_iga = plvds_setting_info->iga_path;
963 int mode_bpp = plvds_setting_info->bpp;
964 int viafb_load_reg_num = 0;
965 int reg_value = 0;
966 int set_hres, set_vres;
967 int panel_hres, panel_vres;
968 u32 pll_D_N;
969 int offset;
970 struct io_register *reg = NULL;
971 struct display_timing mode_crt_reg, panel_crt_reg;
972 struct crt_mode_table *panel_crt_table = NULL;
973 struct VideoModeTable *vmode_tbl = NULL;
974
975 DEBUG_MSG(KERN_INFO "viafb_lcd_set_mode!!\n");
976 /* Get mode table */
977 mode_crt_reg = mode_crt_table->crtc;
978 /* Get panel table Pointer */
979 vmode_tbl = viafb_get_modetbl_pointer(video_index);
980 panel_crt_table = vmode_tbl->crtc;
981 panel_crt_reg = panel_crt_table->crtc;
982 DEBUG_MSG(KERN_INFO "bellow viafb_lcd_set_mode!!\n");
983 set_hres = plvds_setting_info->h_active;
984 set_vres = plvds_setting_info->v_active;
985 panel_hres = plvds_setting_info->lcd_panel_hres;
986 panel_vres = plvds_setting_info->lcd_panel_vres;
987 if (VT1636_LVDS == plvds_chip_info->lvds_chip_name)
988 viafb_init_lvds_vt1636(plvds_setting_info, plvds_chip_info);
989 plvds_setting_info->vclk = panel_crt_table->clk;
990 if (set_iga == IGA1) {
991 /* IGA1 doesn't have LCD scaling, so set it as centering. */
992 viafb_load_crtc_timing(lcd_centering_timging
993 (mode_crt_reg, panel_crt_reg), IGA1);
994 } else {
995 /* Expansion */
996 if ((plvds_setting_info->display_method ==
997 LCD_EXPANDSION) & ((set_hres != panel_hres)
998 || (set_vres != panel_vres))) {
999 /* expansion timing IGA2 loaded panel set timing*/
1000 viafb_load_crtc_timing(panel_crt_reg, IGA2);
1001 DEBUG_MSG(KERN_INFO "viafb_load_crtc_timing!!\n");
1002 load_lcd_scaling(set_hres, set_vres, panel_hres,
1003 panel_vres);
1004 DEBUG_MSG(KERN_INFO "load_lcd_scaling!!\n");
1005 } else { /* Centering */
1006 /* centering timing IGA2 always loaded panel
1007 and mode releative timing */
1008 viafb_load_crtc_timing(lcd_centering_timging
1009 (mode_crt_reg, panel_crt_reg), IGA2);
1010 viafb_write_reg_mask(CR79, VIACR, 0x00,
1011 BIT0 + BIT1 + BIT2);
1012 /* LCD scaling disabled */
1013 }
1014 }
1015
1016 if (set_iga == IGA1_IGA2) {
1017 load_crtc_shadow_timing(mode_crt_reg, panel_crt_reg);
1018 /* Fill shadow registers */
1019
1020 switch (plvds_setting_info->lcd_panel_id) {
1021 case LCD_PANEL_ID0_640X480:
1022 offset = 80;
1023 break;
1024 case LCD_PANEL_ID1_800X600:
1025 case LCD_PANEL_IDA_800X480:
1026 offset = 110;
1027 break;
1028 case LCD_PANEL_ID2_1024X768:
1029 offset = 150;
1030 break;
1031 case LCD_PANEL_ID3_1280X768:
1032 case LCD_PANEL_ID4_1280X1024:
1033 case LCD_PANEL_ID5_1400X1050:
1034 case LCD_PANEL_ID9_1280X800:
1035 offset = 190;
1036 break;
1037 case LCD_PANEL_ID6_1600X1200:
1038 offset = 250;
1039 break;
1040 case LCD_PANEL_ID7_1366X768:
1041 case LCD_PANEL_IDB_1360X768:
1042 offset = 212;
1043 break;
1044 default:
1045 offset = 140;
1046 break;
1047 }
1048
1049 /* Offset for simultaneous */
1050 reg_value = offset;
1051 viafb_load_reg_num = offset_reg.iga2_offset_reg.reg_num;
1052 reg = offset_reg.iga2_offset_reg.reg;
1053 viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
1054 DEBUG_MSG(KERN_INFO "viafb_load_reg!!\n");
1055 viafb_load_fetch_count_reg(set_hres, 4, IGA2);
1056 /* Fetch count for simultaneous */
1057 } else { /* SAMM */
1058 /* Offset for IGA2 only */
1059 viafb_load_offset_reg(set_hres, mode_bpp / 8, set_iga);
1060 /* Fetch count for IGA2 only */
1061 viafb_load_fetch_count_reg(set_hres, mode_bpp / 8, set_iga);
1062
1063 if ((viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266)
1064 && (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400))
1065 viafb_load_FIFO_reg(set_iga, set_hres, set_vres);
1066
1067 viafb_set_color_depth(mode_bpp / 8, set_iga);
1068 }
1069
1070 fill_lcd_format();
1071
1072 pll_D_N = viafb_get_clk_value(panel_crt_table[0].clk);
1073 DEBUG_MSG(KERN_INFO "PLL=0x%x", pll_D_N);
1074 viafb_set_vclock(pll_D_N, set_iga);
1075
1076 viafb_set_output_path(DEVICE_LCD, set_iga,
1077 plvds_chip_info->output_interface);
1078 lcd_patch_skew(plvds_setting_info, plvds_chip_info);
1079
1080 /* If K8M800, enable LCD Prefetch Mode. */
1081 if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800)
1082 || (UNICHROME_K8M890 == viaparinfo->chip_info->gfx_chip_name))
1083 viafb_write_reg_mask(CR6A, VIACR, 0x01, BIT0);
1084
1085 load_lcd_patch_regs(set_hres, set_vres,
1086 plvds_setting_info->lcd_panel_id, set_iga);
1087
1088 DEBUG_MSG(KERN_INFO "load_lcd_patch_regs!!\n");
1089
1090 /* Patch for non 32bit alignment mode */
1091 via_pitch_alignment_patch_lcd(plvds_setting_info, plvds_chip_info);
1092}
1093
1094static void integrated_lvds_disable(struct lvds_setting_information
1095 *plvds_setting_info,
1096 struct lvds_chip_information *plvds_chip_info)
1097{
1098 bool turn_off_first_powersequence = false;
1099 bool turn_off_second_powersequence = false;
1100 if (INTERFACE_LVDS0LVDS1 == plvds_chip_info->output_interface)
1101 turn_off_first_powersequence = true;
1102 if (INTERFACE_LVDS0 == plvds_chip_info->output_interface)
1103 turn_off_first_powersequence = true;
1104 if (INTERFACE_LVDS1 == plvds_chip_info->output_interface)
1105 turn_off_second_powersequence = true;
1106 if (turn_off_second_powersequence) {
1107 /* Use second power sequence control: */
1108
1109 /* Turn off power sequence. */
1110 viafb_write_reg_mask(CRD4, VIACR, 0, BIT1);
1111
1112 /* Turn off back light. */
1113 viafb_write_reg_mask(CRD3, VIACR, 0xC0, BIT6 + BIT7);
1114 }
1115 if (turn_off_first_powersequence) {
1116 /* Use first power sequence control: */
1117
1118 /* Turn off power sequence. */
1119 viafb_write_reg_mask(CR6A, VIACR, 0, BIT3);
1120
1121 /* Turn off back light. */
1122 viafb_write_reg_mask(CR91, VIACR, 0xC0, BIT6 + BIT7);
1123 }
1124
1125 /* Turn DFP High/Low Pad off. */
1126 viafb_write_reg_mask(SR2A, VIASR, 0, BIT0 + BIT1 + BIT2 + BIT3);
1127
1128 /* Power off LVDS channel. */
1129 switch (plvds_chip_info->output_interface) {
1130 case INTERFACE_LVDS0:
1131 {
1132 viafb_write_reg_mask(CRD2, VIACR, 0x80, BIT7);
1133 break;
1134 }
1135
1136 case INTERFACE_LVDS1:
1137 {
1138 viafb_write_reg_mask(CRD2, VIACR, 0x40, BIT6);
1139 break;
1140 }
1141
1142 case INTERFACE_LVDS0LVDS1:
1143 {
1144 viafb_write_reg_mask(CRD2, VIACR, 0xC0, BIT6 + BIT7);
1145 break;
1146 }
1147 }
1148}
1149
1150static void integrated_lvds_enable(struct lvds_setting_information
1151 *plvds_setting_info,
1152 struct lvds_chip_information *plvds_chip_info)
1153{
1154 bool turn_on_first_powersequence = false;
1155 bool turn_on_second_powersequence = false;
1156
1157 DEBUG_MSG(KERN_INFO "integrated_lvds_enable, out_interface:%d\n",
1158 plvds_chip_info->output_interface);
1159 if (plvds_setting_info->lcd_mode == LCD_SPWG)
1160 viafb_write_reg_mask(CRD2, VIACR, 0x00, BIT0 + BIT1);
1161 else
1162 viafb_write_reg_mask(CRD2, VIACR, 0x03, BIT0 + BIT1);
1163 if (INTERFACE_LVDS0LVDS1 == plvds_chip_info->output_interface)
1164 turn_on_first_powersequence = true;
1165 if (INTERFACE_LVDS0 == plvds_chip_info->output_interface)
1166 turn_on_first_powersequence = true;
1167 if (INTERFACE_LVDS1 == plvds_chip_info->output_interface)
1168 turn_on_second_powersequence = true;
1169
1170 if (turn_on_second_powersequence) {
1171 /* Use second power sequence control: */
1172
1173 /* Use hardware control power sequence. */
1174 viafb_write_reg_mask(CRD3, VIACR, 0, BIT0);
1175
1176 /* Turn on back light. */
1177 viafb_write_reg_mask(CRD3, VIACR, 0, BIT6 + BIT7);
1178
1179 /* Turn on hardware power sequence. */
1180 viafb_write_reg_mask(CRD4, VIACR, 0x02, BIT1);
1181 }
1182 if (turn_on_first_powersequence) {
1183 /* Use first power sequence control: */
1184
1185 /* Use hardware control power sequence. */
1186 viafb_write_reg_mask(CR91, VIACR, 0, BIT0);
1187
1188 /* Turn on back light. */
1189 viafb_write_reg_mask(CR91, VIACR, 0, BIT6 + BIT7);
1190
1191 /* Turn on hardware power sequence. */
1192 viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3);
1193 }
1194
1195 /* Turn DFP High/Low pad on. */
1196 viafb_write_reg_mask(SR2A, VIASR, 0x0F, BIT0 + BIT1 + BIT2 + BIT3);
1197
1198 /* Power on LVDS channel. */
1199 switch (plvds_chip_info->output_interface) {
1200 case INTERFACE_LVDS0:
1201 {
1202 viafb_write_reg_mask(CRD2, VIACR, 0, BIT7);
1203 break;
1204 }
1205
1206 case INTERFACE_LVDS1:
1207 {
1208 viafb_write_reg_mask(CRD2, VIACR, 0, BIT6);
1209 break;
1210 }
1211
1212 case INTERFACE_LVDS0LVDS1:
1213 {
1214 viafb_write_reg_mask(CRD2, VIACR, 0, BIT6 + BIT7);
1215 break;
1216 }
1217 }
1218}
1219
1220void viafb_lcd_disable(void)
1221{
1222
1223 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
1224 lcd_powersequence_off();
1225 /* DI1 pad off */
1226 viafb_write_reg_mask(SR1E, VIASR, 0x00, 0x30);
1227 } else if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
1228 if (viafb_LCD2_ON
1229 && (INTEGRATED_LVDS ==
1230 viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name))
1231 integrated_lvds_disable(viaparinfo->lvds_setting_info,
1232 &viaparinfo->chip_info->lvds_chip_info2);
1233 if (INTEGRATED_LVDS ==
1234 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name)
1235 integrated_lvds_disable(viaparinfo->lvds_setting_info,
1236 &viaparinfo->chip_info->lvds_chip_info);
1237 if (VT1636_LVDS == viaparinfo->chip_info->
1238 lvds_chip_info.lvds_chip_name)
1239 viafb_disable_lvds_vt1636(viaparinfo->lvds_setting_info,
1240 &viaparinfo->chip_info->lvds_chip_info);
1241 } else if (VT1636_LVDS ==
1242 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
1243 viafb_disable_lvds_vt1636(viaparinfo->lvds_setting_info,
1244 &viaparinfo->chip_info->lvds_chip_info);
1245 } else {
1246 /* DFP-HL pad off */
1247 viafb_write_reg_mask(SR2A, VIASR, 0x00, 0x0F);
1248 /* Backlight off */
1249 viafb_write_reg_mask(SR3D, VIASR, 0x00, 0x20);
1250 /* 24 bit DI data paht off */
1251 viafb_write_reg_mask(CR91, VIACR, 0x80, 0x80);
1252 /* Simultaneout disabled */
1253 viafb_write_reg_mask(CR6B, VIACR, 0x00, 0x08);
1254 }
1255
1256 /* Disable expansion bit */
1257 viafb_write_reg_mask(CR79, VIACR, 0x00, 0x01);
1258 /* CRT path set to IGA1 */
1259 viafb_write_reg_mask(SR16, VIASR, 0x00, 0x40);
1260 /* Simultaneout disabled */
1261 viafb_write_reg_mask(CR6B, VIACR, 0x00, 0x08);
1262 /* IGA2 path disabled */
1263 viafb_write_reg_mask(CR6A, VIACR, 0x00, 0x80);
1264
1265}
1266
1267void viafb_lcd_enable(void)
1268{
1269 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
1270 /* DI1 pad on */
1271 viafb_write_reg_mask(SR1E, VIASR, 0x30, 0x30);
1272 lcd_powersequence_on();
1273 } else if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
1274 if (viafb_LCD2_ON && (INTEGRATED_LVDS ==
1275 viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name))
1276 integrated_lvds_enable(viaparinfo->lvds_setting_info2, \
1277 &viaparinfo->chip_info->lvds_chip_info2);
1278 if (INTEGRATED_LVDS ==
1279 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name)
1280 integrated_lvds_enable(viaparinfo->lvds_setting_info,
1281 &viaparinfo->chip_info->lvds_chip_info);
1282 if (VT1636_LVDS == viaparinfo->chip_info->
1283 lvds_chip_info.lvds_chip_name)
1284 viafb_enable_lvds_vt1636(viaparinfo->
1285 lvds_setting_info, &viaparinfo->chip_info->
1286 lvds_chip_info);
1287 } else if (VT1636_LVDS ==
1288 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
1289 viafb_enable_lvds_vt1636(viaparinfo->lvds_setting_info,
1290 &viaparinfo->chip_info->lvds_chip_info);
1291 } else {
1292 /* DFP-HL pad on */
1293 viafb_write_reg_mask(SR2A, VIASR, 0x0F, 0x0F);
1294 /* Backlight on */
1295 viafb_write_reg_mask(SR3D, VIASR, 0x20, 0x20);
1296 /* 24 bit DI data paht on */
1297 viafb_write_reg_mask(CR91, VIACR, 0x00, 0x80);
1298
1299 /* Set data source selection bit by iga path */
1300 if (viaparinfo->lvds_setting_info->iga_path == IGA1) {
1301 /* DFP-H set to IGA1 */
1302 viafb_write_reg_mask(CR97, VIACR, 0x00, 0x10);
1303 /* DFP-L set to IGA1 */
1304 viafb_write_reg_mask(CR99, VIACR, 0x00, 0x10);
1305 } else {
1306 /* DFP-H set to IGA2 */
1307 viafb_write_reg_mask(CR97, VIACR, 0x10, 0x10);
1308 /* DFP-L set to IGA2 */
1309 viafb_write_reg_mask(CR99, VIACR, 0x10, 0x10);
1310 }
1311 /* LCD enabled */
1312 viafb_write_reg_mask(CR6A, VIACR, 0x48, 0x48);
1313 }
1314
1315 if ((viaparinfo->lvds_setting_info->iga_path == IGA1)
1316 || (viaparinfo->lvds_setting_info->iga_path == IGA1_IGA2)) {
1317 /* CRT path set to IGA2 */
1318 viafb_write_reg_mask(SR16, VIASR, 0x40, 0x40);
1319 /* IGA2 path disabled */
1320 viafb_write_reg_mask(CR6A, VIACR, 0x00, 0x80);
1321 /* IGA2 path enabled */
1322 } else { /* IGA2 */
1323 viafb_write_reg_mask(CR6A, VIACR, 0x80, 0x80);
1324 }
1325
1326}
1327
1328static void lcd_powersequence_off(void)
1329{
1330 int i, mask, data;
1331
1332 /* Software control power sequence */
1333 viafb_write_reg_mask(CR91, VIACR, 0x11, 0x11);
1334
1335 for (i = 0; i < 3; i++) {
1336 mask = PowerSequenceOff[0][i];
1337 data = PowerSequenceOff[1][i] & mask;
1338 viafb_write_reg_mask(CR91, VIACR, (u8) data, (u8) mask);
1339 udelay(PowerSequenceOff[2][i]);
1340 }
1341
1342 /* Disable LCD */
1343 viafb_write_reg_mask(CR6A, VIACR, 0x00, 0x08);
1344}
1345
1346static void lcd_powersequence_on(void)
1347{
1348 int i, mask, data;
1349
1350 /* Software control power sequence */
1351 viafb_write_reg_mask(CR91, VIACR, 0x11, 0x11);
1352
1353 /* Enable LCD */
1354 viafb_write_reg_mask(CR6A, VIACR, 0x08, 0x08);
1355
1356 for (i = 0; i < 3; i++) {
1357 mask = PowerSequenceOn[0][i];
1358 data = PowerSequenceOn[1][i] & mask;
1359 viafb_write_reg_mask(CR91, VIACR, (u8) data, (u8) mask);
1360 udelay(PowerSequenceOn[2][i]);
1361 }
1362
1363 udelay(1);
1364}
1365
1366static void fill_lcd_format(void)
1367{
1368 u8 bdithering = 0, bdual = 0;
1369
1370 if (viaparinfo->lvds_setting_info->device_lcd_dualedge)
1371 bdual = BIT4;
1372 if (viaparinfo->lvds_setting_info->LCDDithering)
1373 bdithering = BIT0;
1374 /* Dual & Dithering */
1375 viafb_write_reg_mask(CR88, VIACR, (bdithering | bdual), BIT4 + BIT0);
1376}
1377
1378static void check_diport_of_integrated_lvds(
1379 struct lvds_chip_information *plvds_chip_info,
1380 struct lvds_setting_information
1381 *plvds_setting_info)
1382{
1383 /* Determine LCD DI Port by hardware layout. */
1384 switch (viafb_display_hardware_layout) {
1385 case HW_LAYOUT_LCD_ONLY:
1386 {
1387 if (plvds_setting_info->device_lcd_dualedge) {
1388 plvds_chip_info->output_interface =
1389 INTERFACE_LVDS0LVDS1;
1390 } else {
1391 plvds_chip_info->output_interface =
1392 INTERFACE_LVDS0;
1393 }
1394
1395 break;
1396 }
1397
1398 case HW_LAYOUT_DVI_ONLY:
1399 {
1400 plvds_chip_info->output_interface = INTERFACE_NONE;
1401 break;
1402 }
1403
1404 case HW_LAYOUT_LCD1_LCD2:
1405 case HW_LAYOUT_LCD_EXTERNAL_LCD2:
1406 {
1407 plvds_chip_info->output_interface =
1408 INTERFACE_LVDS0LVDS1;
1409 break;
1410 }
1411
1412 case HW_LAYOUT_LCD_DVI:
1413 {
1414 plvds_chip_info->output_interface = INTERFACE_LVDS1;
1415 break;
1416 }
1417
1418 default:
1419 {
1420 plvds_chip_info->output_interface = INTERFACE_LVDS1;
1421 break;
1422 }
1423 }
1424
1425 DEBUG_MSG(KERN_INFO
1426 "Display Hardware Layout: 0x%x, LCD DI Port: 0x%x\n",
1427 viafb_display_hardware_layout,
1428 plvds_chip_info->output_interface);
1429}
1430
1431void viafb_init_lvds_output_interface(struct lvds_chip_information
1432 *plvds_chip_info,
1433 struct lvds_setting_information
1434 *plvds_setting_info)
1435{
1436 if (INTERFACE_NONE != plvds_chip_info->output_interface) {
1437 /*Do nothing, lcd port is specified by module parameter */
1438 return;
1439 }
1440
1441 switch (plvds_chip_info->lvds_chip_name) {
1442
1443 case VT1636_LVDS:
1444 switch (viaparinfo->chip_info->gfx_chip_name) {
1445 case UNICHROME_CX700:
1446 plvds_chip_info->output_interface = INTERFACE_DVP1;
1447 break;
1448 case UNICHROME_CN700:
1449 plvds_chip_info->output_interface = INTERFACE_DFP_LOW;
1450 break;
1451 default:
1452 plvds_chip_info->output_interface = INTERFACE_DVP0;
1453 break;
1454 }
1455 break;
1456
1457 case INTEGRATED_LVDS:
1458 check_diport_of_integrated_lvds(plvds_chip_info,
1459 plvds_setting_info);
1460 break;
1461
1462 default:
1463 switch (viaparinfo->chip_info->gfx_chip_name) {
1464 case UNICHROME_K8M890:
1465 case UNICHROME_P4M900:
1466 case UNICHROME_P4M890:
1467 plvds_chip_info->output_interface = INTERFACE_DFP_LOW;
1468 break;
1469 default:
1470 plvds_chip_info->output_interface = INTERFACE_DFP;
1471 break;
1472 }
1473 break;
1474 }
1475}
1476
1477static struct display_timing lcd_centering_timging(struct display_timing
1478 mode_crt_reg,
1479 struct display_timing panel_crt_reg)
1480{
1481 struct display_timing crt_reg;
1482
1483 crt_reg.hor_total = panel_crt_reg.hor_total;
1484 crt_reg.hor_addr = mode_crt_reg.hor_addr;
1485 crt_reg.hor_blank_start =
1486 (panel_crt_reg.hor_addr - mode_crt_reg.hor_addr) / 2 +
1487 crt_reg.hor_addr;
1488 crt_reg.hor_blank_end = panel_crt_reg.hor_blank_end;
1489 crt_reg.hor_sync_start =
1490 (panel_crt_reg.hor_sync_start -
1491 panel_crt_reg.hor_blank_start) + crt_reg.hor_blank_start;
1492 crt_reg.hor_sync_end = panel_crt_reg.hor_sync_end;
1493
1494 crt_reg.ver_total = panel_crt_reg.ver_total;
1495 crt_reg.ver_addr = mode_crt_reg.ver_addr;
1496 crt_reg.ver_blank_start =
1497 (panel_crt_reg.ver_addr - mode_crt_reg.ver_addr) / 2 +
1498 crt_reg.ver_addr;
1499 crt_reg.ver_blank_end = panel_crt_reg.ver_blank_end;
1500 crt_reg.ver_sync_start =
1501 (panel_crt_reg.ver_sync_start -
1502 panel_crt_reg.ver_blank_start) + crt_reg.ver_blank_start;
1503 crt_reg.ver_sync_end = panel_crt_reg.ver_sync_end;
1504
1505 return crt_reg;
1506}
1507
1508static void load_crtc_shadow_timing(struct display_timing mode_timing,
1509 struct display_timing panel_timing)
1510{
1511 struct io_register *reg = NULL;
1512 int i;
1513 int viafb_load_reg_Num = 0;
1514 int reg_value = 0;
1515
1516 if (viaparinfo->lvds_setting_info->display_method == LCD_EXPANDSION) {
1517 /* Expansion */
1518 for (i = 12; i < 20; i++) {
1519 switch (i) {
1520 case H_TOTAL_SHADOW_INDEX:
1521 reg_value =
1522 IGA2_HOR_TOTAL_SHADOW_FORMULA
1523 (panel_timing.hor_total);
1524 viafb_load_reg_Num =
1525 iga2_shadow_crtc_reg.hor_total_shadow.
1526 reg_num;
1527 reg = iga2_shadow_crtc_reg.hor_total_shadow.reg;
1528 break;
1529 case H_BLANK_END_SHADOW_INDEX:
1530 reg_value =
1531 IGA2_HOR_BLANK_END_SHADOW_FORMULA
1532 (panel_timing.hor_blank_start,
1533 panel_timing.hor_blank_end);
1534 viafb_load_reg_Num =
1535 iga2_shadow_crtc_reg.
1536 hor_blank_end_shadow.reg_num;
1537 reg =
1538 iga2_shadow_crtc_reg.
1539 hor_blank_end_shadow.reg;
1540 break;
1541 case V_TOTAL_SHADOW_INDEX:
1542 reg_value =
1543 IGA2_VER_TOTAL_SHADOW_FORMULA
1544 (panel_timing.ver_total);
1545 viafb_load_reg_Num =
1546 iga2_shadow_crtc_reg.ver_total_shadow.
1547 reg_num;
1548 reg = iga2_shadow_crtc_reg.ver_total_shadow.reg;
1549 break;
1550 case V_ADDR_SHADOW_INDEX:
1551 reg_value =
1552 IGA2_VER_ADDR_SHADOW_FORMULA
1553 (panel_timing.ver_addr);
1554 viafb_load_reg_Num =
1555 iga2_shadow_crtc_reg.ver_addr_shadow.
1556 reg_num;
1557 reg = iga2_shadow_crtc_reg.ver_addr_shadow.reg;
1558 break;
1559 case V_BLANK_SATRT_SHADOW_INDEX:
1560 reg_value =
1561 IGA2_VER_BLANK_START_SHADOW_FORMULA
1562 (panel_timing.ver_blank_start);
1563 viafb_load_reg_Num =
1564 iga2_shadow_crtc_reg.
1565 ver_blank_start_shadow.reg_num;
1566 reg =
1567 iga2_shadow_crtc_reg.
1568 ver_blank_start_shadow.reg;
1569 break;
1570 case V_BLANK_END_SHADOW_INDEX:
1571 reg_value =
1572 IGA2_VER_BLANK_END_SHADOW_FORMULA
1573 (panel_timing.ver_blank_start,
1574 panel_timing.ver_blank_end);
1575 viafb_load_reg_Num =
1576 iga2_shadow_crtc_reg.
1577 ver_blank_end_shadow.reg_num;
1578 reg =
1579 iga2_shadow_crtc_reg.
1580 ver_blank_end_shadow.reg;
1581 break;
1582 case V_SYNC_SATRT_SHADOW_INDEX:
1583 reg_value =
1584 IGA2_VER_SYNC_START_SHADOW_FORMULA
1585 (panel_timing.ver_sync_start);
1586 viafb_load_reg_Num =
1587 iga2_shadow_crtc_reg.
1588 ver_sync_start_shadow.reg_num;
1589 reg =
1590 iga2_shadow_crtc_reg.
1591 ver_sync_start_shadow.reg;
1592 break;
1593 case V_SYNC_END_SHADOW_INDEX:
1594 reg_value =
1595 IGA2_VER_SYNC_END_SHADOW_FORMULA
1596 (panel_timing.ver_sync_start,
1597 panel_timing.ver_sync_end);
1598 viafb_load_reg_Num =
1599 iga2_shadow_crtc_reg.
1600 ver_sync_end_shadow.reg_num;
1601 reg =
1602 iga2_shadow_crtc_reg.
1603 ver_sync_end_shadow.reg;
1604 break;
1605 }
1606 viafb_load_reg(reg_value,
1607 viafb_load_reg_Num, reg, VIACR);
1608 }
1609 } else { /* Centering */
1610 for (i = 12; i < 20; i++) {
1611 switch (i) {
1612 case H_TOTAL_SHADOW_INDEX:
1613 reg_value =
1614 IGA2_HOR_TOTAL_SHADOW_FORMULA
1615 (panel_timing.hor_total);
1616 viafb_load_reg_Num =
1617 iga2_shadow_crtc_reg.hor_total_shadow.
1618 reg_num;
1619 reg = iga2_shadow_crtc_reg.hor_total_shadow.reg;
1620 break;
1621 case H_BLANK_END_SHADOW_INDEX:
1622 reg_value =
1623 IGA2_HOR_BLANK_END_SHADOW_FORMULA
1624 (panel_timing.hor_blank_start,
1625 panel_timing.hor_blank_end);
1626 viafb_load_reg_Num =
1627 iga2_shadow_crtc_reg.
1628 hor_blank_end_shadow.reg_num;
1629 reg =
1630 iga2_shadow_crtc_reg.
1631 hor_blank_end_shadow.reg;
1632 break;
1633 case V_TOTAL_SHADOW_INDEX:
1634 reg_value =
1635 IGA2_VER_TOTAL_SHADOW_FORMULA
1636 (panel_timing.ver_total);
1637 viafb_load_reg_Num =
1638 iga2_shadow_crtc_reg.ver_total_shadow.
1639 reg_num;
1640 reg = iga2_shadow_crtc_reg.ver_total_shadow.reg;
1641 break;
1642 case V_ADDR_SHADOW_INDEX:
1643 reg_value =
1644 IGA2_VER_ADDR_SHADOW_FORMULA
1645 (mode_timing.ver_addr);
1646 viafb_load_reg_Num =
1647 iga2_shadow_crtc_reg.ver_addr_shadow.
1648 reg_num;
1649 reg = iga2_shadow_crtc_reg.ver_addr_shadow.reg;
1650 break;
1651 case V_BLANK_SATRT_SHADOW_INDEX:
1652 reg_value =
1653 IGA2_VER_BLANK_START_SHADOW_FORMULA
1654 (mode_timing.ver_blank_start);
1655 viafb_load_reg_Num =
1656 iga2_shadow_crtc_reg.
1657 ver_blank_start_shadow.reg_num;
1658 reg =
1659 iga2_shadow_crtc_reg.
1660 ver_blank_start_shadow.reg;
1661 break;
1662 case V_BLANK_END_SHADOW_INDEX:
1663 reg_value =
1664 IGA2_VER_BLANK_END_SHADOW_FORMULA
1665 (panel_timing.ver_blank_start,
1666 panel_timing.ver_blank_end);
1667 viafb_load_reg_Num =
1668 iga2_shadow_crtc_reg.
1669 ver_blank_end_shadow.reg_num;
1670 reg =
1671 iga2_shadow_crtc_reg.
1672 ver_blank_end_shadow.reg;
1673 break;
1674 case V_SYNC_SATRT_SHADOW_INDEX:
1675 reg_value =
1676 IGA2_VER_SYNC_START_SHADOW_FORMULA(
1677 (panel_timing.ver_sync_start -
1678 panel_timing.ver_blank_start) +
1679 (panel_timing.ver_addr -
1680 mode_timing.ver_addr) / 2 +
1681 mode_timing.ver_addr);
1682 viafb_load_reg_Num =
1683 iga2_shadow_crtc_reg.ver_sync_start_shadow.
1684 reg_num;
1685 reg =
1686 iga2_shadow_crtc_reg.ver_sync_start_shadow.
1687 reg;
1688 break;
1689 case V_SYNC_END_SHADOW_INDEX:
1690 reg_value =
1691 IGA2_VER_SYNC_END_SHADOW_FORMULA(
1692 (panel_timing.ver_sync_start -
1693 panel_timing.ver_blank_start) +
1694 (panel_timing.ver_addr -
1695 mode_timing.ver_addr) / 2 +
1696 mode_timing.ver_addr,
1697 panel_timing.ver_sync_end);
1698 viafb_load_reg_Num =
1699 iga2_shadow_crtc_reg.ver_sync_end_shadow.
1700 reg_num;
1701 reg =
1702 iga2_shadow_crtc_reg.ver_sync_end_shadow.
1703 reg;
1704 break;
1705 }
1706 viafb_load_reg(reg_value,
1707 viafb_load_reg_Num, reg, VIACR);
1708 }
1709 }
1710}
1711
1712bool viafb_lcd_get_mobile_state(bool *mobile)
1713{
1714 unsigned char *romptr, *tableptr;
1715 u8 core_base;
1716 unsigned char *biosptr;
1717 /* Rom address */
1718 u32 romaddr = 0x000C0000;
1719 u16 start_pattern = 0;
1720
1721 biosptr = ioremap(romaddr, 0x10000);
1722
1723 memcpy(&start_pattern, biosptr, 2);
1724 /* Compare pattern */
1725 if (start_pattern == 0xAA55) {
1726 /* Get the start of Table */
1727 /* 0x1B means BIOS offset position */
1728 romptr = biosptr + 0x1B;
1729 tableptr = biosptr + *((u16 *) romptr);
1730
1731 /* Get the start of biosver structure */
1732 /* 18 means BIOS version position. */
1733 romptr = tableptr + 18;
1734 romptr = biosptr + *((u16 *) romptr);
1735
1736 /* The offset should be 44, but the
1737 actual image is less three char. */
1738 /* pRom += 44; */
1739 romptr += 41;
1740
1741 core_base = *romptr++;
1742
1743 if (core_base & 0x8)
1744 *mobile = false;
1745 else
1746 *mobile = true;
1747 /* release memory */
1748 iounmap(biosptr);
1749
1750 return true;
1751 } else {
1752 iounmap(biosptr);
1753 return false;
1754 }
1755}
1756
1757static void viafb_load_scaling_factor_for_p4m900(int set_hres,
1758 int set_vres, int panel_hres, int panel_vres)
1759{
1760 int h_scaling_factor;
1761 int v_scaling_factor;
1762 u8 cra2 = 0;
1763 u8 cr77 = 0;
1764 u8 cr78 = 0;
1765 u8 cr79 = 0;
1766 u8 cr9f = 0;
1767 /* Check if expansion for horizontal */
1768 if (set_hres < panel_hres) {
1769 /* Load Horizontal Scaling Factor */
1770
1771 /* For VIA_K8M800 or later chipsets. */
1772 h_scaling_factor =
1773 K800_LCD_HOR_SCF_FORMULA(set_hres, panel_hres);
1774 /* HSCaleFactor[1:0] at CR9F[1:0] */
1775 cr9f = h_scaling_factor & 0x0003;
1776 /* HSCaleFactor[9:2] at CR77[7:0] */
1777 cr77 = (h_scaling_factor & 0x03FC) >> 2;
1778 /* HSCaleFactor[11:10] at CR79[5:4] */
1779 cr79 = (h_scaling_factor & 0x0C00) >> 10;
1780 cr79 <<= 4;
1781
1782 /* Horizontal scaling enabled */
1783 cra2 = 0xC0;
1784
1785 DEBUG_MSG(KERN_INFO "Horizontal Scaling value = %d\n",
1786 h_scaling_factor);
1787 } else {
1788 /* Horizontal scaling disabled */
1789 cra2 = 0x00;
1790 }
1791
1792 /* Check if expansion for vertical */
1793 if (set_vres < panel_vres) {
1794 /* Load Vertical Scaling Factor */
1795
1796 /* For VIA_K8M800 or later chipsets. */
1797 v_scaling_factor =
1798 K800_LCD_VER_SCF_FORMULA(set_vres, panel_vres);
1799
1800 /* Vertical scaling enabled */
1801 cra2 |= 0x08;
1802 /* VSCaleFactor[0] at CR79[3] */
1803 cr79 |= ((v_scaling_factor & 0x0001) << 3);
1804 /* VSCaleFactor[8:1] at CR78[7:0] */
1805 cr78 |= (v_scaling_factor & 0x01FE) >> 1;
1806 /* VSCaleFactor[10:9] at CR79[7:6] */
1807 cr79 |= ((v_scaling_factor & 0x0600) >> 9) << 6;
1808
1809 DEBUG_MSG(KERN_INFO "Vertical Scaling value = %d\n",
1810 v_scaling_factor);
1811 } else {
1812 /* Vertical scaling disabled */
1813 cra2 |= 0x00;
1814 }
1815
1816 viafb_write_reg_mask(CRA2, VIACR, cra2, BIT3 + BIT6 + BIT7);
1817 viafb_write_reg_mask(CR77, VIACR, cr77, 0xFF);
1818 viafb_write_reg_mask(CR78, VIACR, cr78, 0xFF);
1819 viafb_write_reg_mask(CR79, VIACR, cr79, 0xF8);
1820 viafb_write_reg_mask(CR9F, VIACR, cr9f, BIT0 + BIT1);
1821}
diff --git a/drivers/video/via/lcd.h b/drivers/video/via/lcd.h
new file mode 100644
index 000000000000..071f47cf5be1
--- /dev/null
+++ b/drivers/video/via/lcd.h
@@ -0,0 +1,94 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
14 * for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21#ifndef __LCD_H__
22#define __LCD_H__
23
24/*Definition TMDS Device ID register*/
25#define VT1631_DEVICE_ID_REG 0x02
26#define VT1631_DEVICE_ID 0x92
27
28#define VT3271_DEVICE_ID_REG 0x02
29#define VT3271_DEVICE_ID 0x71
30
31#define GET_LCD_SIZE_BY_SYSTEM_BIOS 0x01
32#define GET_LCD_SIZE_BY_VGA_BIOS 0x02
33#define GET_LCD_SZIE_BY_HW_STRAPPING 0x03
34#define GET_LCD_SIZE_BY_USER_SETTING 0x04
35
36/* Definition DVI Panel ID*/
37/* Resolution: 640x480, Channel: single, Dithering: Enable */
38#define LCD_PANEL_ID0_640X480 0x00
39/* Resolution: 800x600, Channel: single, Dithering: Enable */
40#define LCD_PANEL_ID1_800X600 0x01
41/* Resolution: 1024x768, Channel: single, Dithering: Enable */
42#define LCD_PANEL_ID2_1024X768 0x02
43/* Resolution: 1280x768, Channel: single, Dithering: Enable */
44#define LCD_PANEL_ID3_1280X768 0x03
45/* Resolution: 1280x1024, Channel: dual, Dithering: Enable */
46#define LCD_PANEL_ID4_1280X1024 0x04
47/* Resolution: 1400x1050, Channel: dual, Dithering: Enable */
48#define LCD_PANEL_ID5_1400X1050 0x05
49/* Resolution: 1600x1200, Channel: dual, Dithering: Enable */
50#define LCD_PANEL_ID6_1600X1200 0x06
51/* Resolution: 1366x768, Channel: single, Dithering: Disable */
52#define LCD_PANEL_ID7_1366X768 0x07
53/* Resolution: 1024x600, Channel: single, Dithering: Enable*/
54#define LCD_PANEL_ID8_1024X600 0x08
55/* Resolution: 1280x800, Channel: single, Dithering: Enable*/
56#define LCD_PANEL_ID9_1280X800 0x09
57/* Resolution: 800x480, Channel: single, Dithering: Enable*/
58#define LCD_PANEL_IDA_800X480 0x0A
59/* Resolution: 1360x768, Channel: single, Dithering: Disable*/
60#define LCD_PANEL_IDB_1360X768 0x0B
61/* Resolution: 480x640, Channel: single, Dithering: Enable */
62#define LCD_PANEL_IDC_480X640 0x0C
63
64
65extern int viafb_LCD2_ON;
66extern int viafb_LCD_ON;
67extern int viafb_DVI_ON;
68
69void viafb_disable_lvds_vt1636(struct lvds_setting_information
70 *plvds_setting_info,
71 struct lvds_chip_information *plvds_chip_info);
72void viafb_enable_lvds_vt1636(struct lvds_setting_information
73 *plvds_setting_info,
74 struct lvds_chip_information *plvds_chip_info);
75void viafb_lcd_disable(void);
76void viafb_lcd_enable(void);
77void viafb_init_lcd_size(void);
78void viafb_init_lvds_output_interface(struct lvds_chip_information
79 *plvds_chip_info,
80 struct lvds_setting_information
81 *plvds_setting_info);
82void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,
83 struct lvds_setting_information *plvds_setting_info,
84 struct lvds_chip_information *plvds_chip_info);
85int viafb_lvds_trasmitter_identify(void);
86void viafb_init_lvds_output_interface(struct lvds_chip_information
87 *plvds_chip_info,
88 struct lvds_setting_information
89 *plvds_setting_info);
90bool viafb_lcd_get_mobile_state(bool *mobile);
91void viafb_load_crtc_timing(struct display_timing device_timing,
92 int set_iga);
93
94#endif /* __LCD_H__ */
diff --git a/drivers/video/via/lcdtbl.h b/drivers/video/via/lcdtbl.h
new file mode 100644
index 000000000000..6f3dd800be59
--- /dev/null
+++ b/drivers/video/via/lcdtbl.h
@@ -0,0 +1,591 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
14 * for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21#ifndef __LCDTBL_H__
22#define __LCDTBL_H__
23
24#include "share.h"
25
26/* CLE266 Software Power Sequence */
27/* {Mask}, {Data}, {Delay} */
28int PowerSequenceOn[3][3] =
29 { {0x10, 0x08, 0x06}, {0x10, 0x08, 0x06}, {0x19, 0x1FE, 0x01} };
30int PowerSequenceOff[3][3] =
31 { {0x06, 0x08, 0x10}, {0x00, 0x00, 0x00}, {0xD2, 0x19, 0x01} };
32
33/* ++++++ P880 ++++++ */
34/* Panel 1600x1200 */
35struct io_reg P880_LCD_RES_6X4_16X12[] = {
36 /*IGA2 Horizontal Total */
37 {VIACR, CR50, 0xFF, 0x73}, {VIACR, CR55, 0x0F, 0x08},
38 /*IGA2 Horizontal Blank End */
39 {VIACR, CR53, 0xFF, 0x73}, {VIACR, CR54, 0x38, 0x00},
40 {VIACR, CR5D, 0x40, 0x40},
41 /*IGA2 Horizontal Total Shadow */
42 {VIACR, CR6D, 0xFF, 0x5A}, {VIACR, CR71, 0x08, 0x00},
43 /*IGA2 Horizontal Blank End Shadow */
44 {VIACR, CR6E, 0xFF, 0x5E},
45 /*IGA2 Offset */
46 {VIACR, CR66, 0xFF, 0xD6}, {VIACR, CR67, 0x03, 0x00},
47 /*VCLK*/ {VIASR, SR44, 0xFF, 0x7D}, {VIASR, SR45, 0xFF, 0x8C},
48 {VIASR, SR46, 0xFF, 0x02}
49
50};
51
52#define NUM_TOTAL_P880_LCD_RES_6X4_16X12 ARRAY_SIZE(P880_LCD_RES_6X4_16X12)
53
54struct io_reg P880_LCD_RES_7X4_16X12[] = {
55 /*IGA2 Horizontal Total */
56 {VIACR, CR50, 0xFF, 0x67}, {VIACR, CR55, 0x0F, 0x08},
57 /*IGA2 Horizontal Blank End */
58 {VIACR, CR53, 0xFF, 0x67}, {VIACR, CR54, 0x38, 0x00},
59 {VIACR, CR5D, 0x40, 0x40},
60 /*IGA2 Horizontal Total Shadow */
61 {VIACR, CR6D, 0xFF, 0x74}, {VIACR, CR71, 0x08, 0x00},
62 /*IGA2 Horizontal Blank End Shadow */
63 {VIACR, CR6E, 0xFF, 0x78},
64 /*IGA2 Offset */
65 {VIACR, CR66, 0xFF, 0xF5}, {VIACR, CR67, 0x03, 0x00},
66 /*VCLK*/ {VIASR, SR44, 0xFF, 0x78}, {VIASR, SR45, 0xFF, 0x8C},
67 {VIASR, SR46, 0xFF, 0x01}
68
69};
70
71#define NUM_TOTAL_P880_LCD_RES_7X4_16X12 ARRAY_SIZE(P880_LCD_RES_7X4_16X12)
72
73struct io_reg P880_LCD_RES_8X6_16X12[] = {
74 /*IGA2 Horizontal Total */
75 {VIACR, CR50, 0xFF, 0x65}, {VIACR, CR55, 0x0F, 0x08},
76 /*IGA2 Horizontal Blank End */
77 {VIACR, CR53, 0xFF, 0x65}, {VIACR, CR54, 0x38, 0x00},
78 {VIACR, CR5D, 0x40, 0x40},
79 /*IGA2 Horizontal Total Shadow */
80 {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x00},
81 /*IGA2 Horizontal Blank End Shadow */
82 {VIACR, CR6E, 0xFF, 0x83},
83 /*IGA2 Offset */
84 {VIACR, CR66, 0xFF, 0xE1}, {VIACR, CR67, 0x03, 0x00},
85 /*VCLK*/ {VIASR, SR44, 0xFF, 0x6D}, {VIASR, SR45, 0xFF, 0x88},
86 {VIASR, SR46, 0xFF, 0x03}
87
88};
89
90#define NUM_TOTAL_P880_LCD_RES_8X6_16X12 ARRAY_SIZE(P880_LCD_RES_8X6_16X12)
91
92struct io_reg P880_LCD_RES_10X7_16X12[] = {
93 /*IGA2 Horizontal Total */
94 {VIACR, CR50, 0xFF, 0x65}, {VIACR, CR55, 0x0F, 0x08},
95 /*IGA2 Horizontal Blank End */
96 {VIACR, CR53, 0xFF, 0x65}, {VIACR, CR54, 0x38, 0x00},
97 {VIACR, CR5D, 0x40, 0x40},
98 /*IGA2 Horizontal Total Shadow */
99 {VIACR, CR6D, 0xFF, 0xAB}, {VIACR, CR71, 0x08, 0x00},
100 /*IGA2 Horizontal Blank End Shadow */
101 {VIACR, CR6E, 0xFF, 0xAF},
102 /*IGA2 Offset */
103 {VIACR, CR66, 0xFF, 0xF0}, {VIACR, CR67, 0x03, 0x00},
104 /*VCLK*/ {VIASR, SR44, 0xFF, 0x92}, {VIASR, SR45, 0xFF, 0x88},
105 {VIASR, SR46, 0xFF, 0x03}
106
107};
108
109#define NUM_TOTAL_P880_LCD_RES_10X7_16X12 ARRAY_SIZE(P880_LCD_RES_10X7_16X12)
110
111struct io_reg P880_LCD_RES_12X10_16X12[] = {
112 /*IGA2 Horizontal Total */
113 {VIACR, CR50, 0xFF, 0x7D}, {VIACR, CR55, 0x0F, 0x08},
114 /*IGA2 Horizontal Blank End */
115 {VIACR, CR53, 0xFF, 0x7D}, {VIACR, CR54, 0x38, 0x00},
116 {VIACR, CR5D, 0x40, 0x40},
117 /*IGA2 Horizontal Total Shadow */
118 {VIACR, CR6D, 0xFF, 0xD0}, {VIACR, CR71, 0x08, 0x00},
119 /*IGA2 Horizontal Blank End Shadow */
120 {VIACR, CR6E, 0xFF, 0xD4},
121 /*IGA2 Offset */
122 {VIACR, CR66, 0xFF, 0xFA}, {VIACR, CR67, 0x03, 0x00},
123 /*VCLK*/ {VIASR, SR44, 0xFF, 0xF6}, {VIASR, SR45, 0xFF, 0x88},
124 {VIASR, SR46, 0xFF, 0x05}
125
126};
127
128#define NUM_TOTAL_P880_LCD_RES_12X10_16X12 ARRAY_SIZE(P880_LCD_RES_12X10_16X12)
129
130/* Panel 1400x1050 */
131struct io_reg P880_LCD_RES_6X4_14X10[] = {
132 /* 640x480 */
133 /* IGA2 Horizontal Total */
134 {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56},
135 /* IGA2 Horizontal Blank End */
136 {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75},
137 {VIACR, CR5D, 0x40, 0x24},
138 /* IGA2 Horizontal Total Shadow */
139 {VIACR, CR6D, 0xFF, 0x5F}, {VIACR, CR71, 0x08, 0x44},
140 /* IGA2 Horizontal Blank End Shadow */
141 {VIACR, CR6E, 0xFF, 0x63},
142 /* IGA2 Offset */
143 {VIACR, CR66, 0xFF, 0xB4}, {VIACR, CR67, 0x03, 0x00},
144 /* VCLK */
145 {VIASR, SR44, 0xFF, 0xC6}, {VIASR, SR45, 0xFF, 0x8C},
146 {VIASR, SR46, 0xFF, 0x05}
147};
148
149#define NUM_TOTAL_P880_LCD_RES_6X4_14X10 ARRAY_SIZE(P880_LCD_RES_6X4_14X10)
150
151struct io_reg P880_LCD_RES_8X6_14X10[] = {
152 /* 800x600 */
153 /* IGA2 Horizontal Total */
154 {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56},
155 /* IGA2 Horizontal Blank End */
156 {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75},
157 {VIACR, CR5D, 0x40, 0x24},
158 /* IGA2 Horizontal Total Shadow */
159 {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x44},
160 /* IGA2 Horizontal Blank End Shadow */
161 {VIACR, CR6E, 0xFF, 0x83},
162 /* IGA2 Offset */
163 {VIACR, CR66, 0xFF, 0xBE}, {VIACR, CR67, 0x03, 0x00},
164 /* VCLK */
165 {VIASR, SR44, 0xFF, 0x06}, {VIASR, SR45, 0xFF, 0x8D},
166 {VIASR, SR46, 0xFF, 0x05}
167};
168
169#define NUM_TOTAL_P880_LCD_RES_8X6_14X10 ARRAY_SIZE(P880_LCD_RES_8X6_14X10)
170
171/* ++++++ K400 ++++++ */
172/* Panel 1600x1200 */
173struct io_reg K400_LCD_RES_6X4_16X12[] = {
174 /*IGA2 Horizontal Total */
175 {VIACR, CR50, 0xFF, 0x73}, {VIACR, CR55, 0x0F, 0x08},
176 /*IGA2 Horizontal Blank End */
177 {VIACR, CR53, 0xFF, 0x73}, {VIACR, CR54, 0x38, 0x00},
178 {VIACR, CR5D, 0x40, 0x40},
179 /*IGA2 Horizontal Total Shadow */
180 {VIACR, CR6D, 0xFF, 0x5A}, {VIACR, CR71, 0x08, 0x00},
181 /*IGA2 Horizontal Blank End Shadow */
182 {VIACR, CR6E, 0xFF, 0x5E},
183 /*IGA2 Offset */
184 {VIACR, CR66, 0xFF, 0xDA}, {VIACR, CR67, 0x03, 0x00},
185 /*VCLK*/ {VIASR, SR46, 0xFF, 0xC4}, {VIASR, SR47, 0xFF, 0x7F}
186};
187
188#define NUM_TOTAL_K400_LCD_RES_6X4_16X12 ARRAY_SIZE(K400_LCD_RES_6X4_16X12)
189
190struct io_reg K400_LCD_RES_7X4_16X12[] = {
191 /*IGA2 Horizontal Total */
192 {VIACR, CR50, 0xFF, 0x67}, {VIACR, CR55, 0x0F, 0x08},
193 /*IGA2 Horizontal Blank End */
194 {VIACR, CR53, 0xFF, 0x67}, {VIACR, CR54, 0x38, 0x00},
195 {VIACR, CR5D, 0x40, 0x40},
196 /*IGA2 Horizontal Total Shadow */
197 {VIACR, CR6D, 0xFF, 0x74}, {VIACR, CR71, 0x08, 0x00},
198 /*IGA2 Horizontal Blank End Shadow */
199 {VIACR, CR6E, 0xFF, 0x78},
200 /*IGA2 Offset */
201 {VIACR, CR66, 0xFF, 0xF5}, {VIACR, CR67, 0x03, 0x00},
202 /*VCLK*/ {VIASR, SR46, 0xFF, 0x46}, {VIASR, SR47, 0xFF, 0x3D}
203};
204
205#define NUM_TOTAL_K400_LCD_RES_7X4_16X12 ARRAY_SIZE(K400_LCD_RES_7X4_16X12)
206
207struct io_reg K400_LCD_RES_8X6_16X12[] = {
208 /*IGA2 Horizontal Total */
209 {VIACR, CR50, 0xFF, 0x65}, {VIACR, CR55, 0x0F, 0x08},
210 /*IGA2 Horizontal Blank End */
211 {VIACR, CR53, 0xFF, 0x65}, {VIACR, CR54, 0x38, 0x00},
212 {VIACR, CR5D, 0x40, 0x40},
213 /*IGA2 Horizontal Total Shadow */
214 {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x00},
215 /*IGA2 Horizontal Blank End Shadow */
216 {VIACR, CR6E, 0xFF, 0x83},
217 /*IGA2 Offset */
218 {VIACR, CR66, 0xFF, 0xE1}, {VIACR, CR67, 0x03, 0x00},
219 /*VCLK*/ {VIASR, SR46, 0xFF, 0x85}, {VIASR, SR47, 0xFF, 0x6F}
220};
221
222#define NUM_TOTAL_K400_LCD_RES_8X6_16X12 ARRAY_SIZE(K400_LCD_RES_8X6_16X12)
223
224struct io_reg K400_LCD_RES_10X7_16X12[] = {
225 /*IGA2 Horizontal Total */
226 {VIACR, CR50, 0xFF, 0x65}, {VIACR, CR55, 0x0F, 0x08},
227 /*IGA2 Horizontal Blank End */
228 {VIACR, CR53, 0xFF, 0x65}, {VIACR, CR54, 0x38, 0x00},
229 {VIACR, CR5D, 0x40, 0x40},
230 /*IGA2 Horizontal Total Shadow */
231 {VIACR, CR6D, 0xFF, 0xAB}, {VIACR, CR71, 0x08, 0x00},
232 /*IGA2 Horizontal Blank End Shadow */
233 {VIACR, CR6E, 0xFF, 0xAF},
234 /*IGA2 Offset */
235 {VIACR, CR66, 0xFF, 0xF0}, {VIACR, CR67, 0x03, 0x00},
236 /*VCLK*/ {VIASR, SR46, 0xFF, 0x45}, {VIASR, SR47, 0xFF, 0x4A}
237};
238
239#define NUM_TOTAL_K400_LCD_RES_10X7_16X12 ARRAY_SIZE(K400_LCD_RES_10X7_16X12)
240
241struct io_reg K400_LCD_RES_12X10_16X12[] = {
242 /*IGA2 Horizontal Total */
243 {VIACR, CR50, 0xFF, 0x7D}, {VIACR, CR55, 0x0F, 0x08},
244 /*IGA2 Horizontal Blank End */
245 {VIACR, CR53, 0xFF, 0x7D}, {VIACR, CR54, 0x38, 0x00},
246 {VIACR, CR5D, 0x40, 0x40},
247 /*IGA2 Horizontal Total Shadow */
248 {VIACR, CR6D, 0xFF, 0xD0}, {VIACR, CR71, 0x08, 0x00},
249 /*IGA2 Horizontal Blank End Shadow */
250 {VIACR, CR6E, 0xFF, 0xD4},
251 /*IGA2 Offset */
252 {VIACR, CR66, 0xFF, 0xFA}, {VIACR, CR67, 0x03, 0x00},
253 /*VCLK*/ {VIASR, SR46, 0xFF, 0x47}, {VIASR, SR47, 0xFF, 0x7C}
254};
255
256#define NUM_TOTAL_K400_LCD_RES_12X10_16X12 ARRAY_SIZE(K400_LCD_RES_12X10_16X12)
257
258/* Panel 1400x1050 */
259struct io_reg K400_LCD_RES_6X4_14X10[] = {
260 /* 640x400 */
261 /* IGA2 Horizontal Total */
262 {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56},
263 /* IGA2 Horizontal Blank End */
264 {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75},
265 {VIACR, CR5D, 0x40, 0x24},
266 /* IGA2 Horizontal Total Shadow */
267 {VIACR, CR6D, 0xFF, 0x5F}, {VIACR, CR71, 0x08, 0x44},
268 /* IGA2 Horizontal Blank End Shadow */
269 {VIACR, CR6E, 0xFF, 0x63},
270 /* IGA2 Offset */
271 {VIACR, CR66, 0xFF, 0xB4}, {VIACR, CR67, 0x03, 0x00},
272 /* VCLK */
273 {VIASR, SR46, 0xFF, 0x07}, {VIASR, SR47, 0xFF, 0x19}
274};
275
276#define NUM_TOTAL_K400_LCD_RES_6X4_14X10 ARRAY_SIZE(K400_LCD_RES_6X4_14X10)
277
278struct io_reg K400_LCD_RES_8X6_14X10[] = {
279 /* 800x600 */
280 /* IGA2 Horizontal Total */
281 {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56},
282 /* IGA2 Horizontal Blank End */
283 {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75},
284 {VIACR, CR5D, 0x40, 0x24},
285 /* IGA2 Horizontal Total Shadow */
286 {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x44},
287 /* IGA2 Horizontal Blank End Shadow */
288 {VIACR, CR6E, 0xFF, 0x83},
289 /* IGA2 Offset */
290 {VIACR, CR66, 0xFF, 0xBE}, {VIACR, CR67, 0x03, 0x00},
291 /* VCLK */
292 {VIASR, SR46, 0xFF, 0x07}, {VIASR, SR47, 0xFF, 0x21}
293};
294
295#define NUM_TOTAL_K400_LCD_RES_8X6_14X10 ARRAY_SIZE(K400_LCD_RES_8X6_14X10)
296
297struct io_reg K400_LCD_RES_10X7_14X10[] = {
298 /* 1024x768 */
299 /* IGA2 Horizontal Total */
300 {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56},
301 /* IGA2 Horizontal Blank End */
302 {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75},
303 {VIACR, CR5D, 0x40, 0x24},
304 /* IGA2 Horizontal Total Shadow */
305 {VIACR, CR6D, 0xFF, 0xA3}, {VIACR, CR71, 0x08, 0x44},
306 /* IGA2 Horizontal Blank End Shadow */
307 {VIACR, CR6E, 0xFF, 0xA7},
308 /* IGA2 Offset */
309 {VIACR, CR66, 0xFF, 0xC3}, {VIACR, CR67, 0x03, 0x04},
310 /* VCLK */
311 {VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x1E}
312};
313
314#define NUM_TOTAL_K400_LCD_RES_10X7_14X10 ARRAY_SIZE(K400_LCD_RES_10X7_14X10)
315
316struct io_reg K400_LCD_RES_12X10_14X10[] = {
317 /* 1280x768, 1280x960, 1280x1024 */
318 /* IGA2 Horizontal Total */
319 {VIACR, CR50, 0xFF, 0x97}, {VIACR, CR55, 0x0F, 0x56},
320 /* IGA2 Horizontal Blank End */
321 {VIACR, CR53, 0xFF, 0x97}, {VIACR, CR54, 0x38, 0x75},
322 {VIACR, CR5D, 0x40, 0x24},
323 /* IGA2 Horizontal Total Shadow */
324 {VIACR, CR6D, 0xFF, 0xCE}, {VIACR, CR71, 0x08, 0x44},
325 /* IGA2 Horizontal Blank End Shadow */
326 {VIACR, CR6E, 0xFF, 0xD2},
327 /* IGA2 Offset */
328 {VIACR, CR66, 0xFF, 0xC9}, {VIACR, CR67, 0x03, 0x04},
329 /* VCLK */
330 {VIASR, SR46, 0xFF, 0x84}, {VIASR, SR47, 0xFF, 0x79}
331};
332
333#define NUM_TOTAL_K400_LCD_RES_12X10_14X10 ARRAY_SIZE(K400_LCD_RES_12X10_14X10)
334
335/* ++++++ K400 ++++++ */
336/* Panel 1366x768 */
337struct io_reg K400_LCD_RES_6X4_1366X7[] = {
338 /* 640x400 */
339 /* IGA2 Horizontal Total */
340 {VIACR, CR50, 0xFF, 0x47}, {VIACR, CR55, 0x0F, 0x35},
341 /* IGA2 Horizontal Blank End */
342 {VIACR, CR53, 0xFF, 0x47}, {VIACR, CR54, 0x38, 0x2B},
343 {VIACR, CR5D, 0x40, 0x13},
344 /* IGA2 Horizontal Total Shadow */
345 {VIACR, CR6D, 0xFF, 0x60}, {VIACR, CR71, 0x08, 0x23},
346 /* IGA2 Horizontal Blank End Shadow */
347 {VIACR, CR6E, 0xFF, 0x64},
348 /* IGA2 Offset */
349 {VIACR, CR66, 0xFF, 0x8C}, {VIACR, CR67, 0x03, 0x00},
350 /* VCLK */
351 {VIASR, SR46, 0xFF, 0x87}, {VIASR, SR47, 0xFF, 0x4C}
352};
353
354#define NUM_TOTAL_K400_LCD_RES_6X4_1366X7 ARRAY_SIZE(K400_LCD_RES_6X4_1366X7)
355
356struct io_reg K400_LCD_RES_7X4_1366X7[] = {
357 /* IGA2 Horizontal Total */
358 {VIACR, CR50, 0xFF, 0x3B}, {VIACR, CR55, 0x0F, 0x35},
359 /* IGA2 Horizontal Blank End */
360 {VIACR, CR53, 0xFF, 0x3B}, {VIACR, CR54, 0x38, 0x2B},
361 {VIACR, CR5D, 0x40, 0x13},
362 /* IGA2 Horizontal Total Shadow */
363 {VIACR, CR6D, 0xFF, 0x71}, {VIACR, CR71, 0x08, 0x23},
364 /* IGA2 Horizontal Blank End Shadow */
365 {VIACR, CR6E, 0xFF, 0x75},
366 /* IGA2 Offset */
367 {VIACR, CR66, 0xFF, 0x96}, {VIACR, CR67, 0x03, 0x00},
368 /* VCLK */
369 {VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x10}
370};
371
372#define NUM_TOTAL_K400_LCD_RES_7X4_1366X7 ARRAY_SIZE(K400_LCD_RES_7X4_1366X7)
373
374struct io_reg K400_LCD_RES_8X6_1366X7[] = {
375 /* 800x600 */
376 /* IGA2 Horizontal Total */
377 {VIACR, CR50, 0xFF, 0x37}, {VIACR, CR55, 0x0F, 0x35},
378 /* IGA2 Horizontal Blank End */
379 {VIACR, CR53, 0xFF, 0x37}, {VIACR, CR54, 0x38, 0x2B},
380 {VIACR, CR5D, 0x40, 0x13},
381 /* IGA2 Horizontal Total Shadow */
382 {VIACR, CR6D, 0xFF, 0x7E}, {VIACR, CR71, 0x08, 0x23},
383 /* IGA2 Horizontal Blank End Shadow */
384 {VIACR, CR6E, 0xFF, 0x82},
385 /* IGA2 Offset */
386 {VIACR, CR66, 0xFF, 0x8C}, {VIACR, CR67, 0x03, 0x00},
387 /* VCLK */
388 {VIASR, SR46, 0xFF, 0x84}, {VIASR, SR47, 0xFF, 0xB9}
389};
390
391#define NUM_TOTAL_K400_LCD_RES_8X6_1366X7 ARRAY_SIZE(K400_LCD_RES_8X6_1366X7)
392
393struct io_reg K400_LCD_RES_10X7_1366X7[] = {
394 /* 1024x768 */
395 /* IGA2 Horizontal Total */
396 {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56},
397 /* IGA2 Horizontal Blank End */
398 {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75},
399 {VIACR, CR5D, 0x40, 0x24},
400 /* IGA2 Horizontal Total Shadow */
401 {VIACR, CR6D, 0xFF, 0xA3}, {VIACR, CR71, 0x08, 0x44},
402 /* IGA2 Horizontal Blank End Shadow */
403 {VIACR, CR6E, 0xFF, 0xA7},
404 /* IGA2 Offset */
405 {VIACR, CR66, 0xFF, 0xC3}, {VIACR, CR67, 0x03, 0x04},
406 /* VCLK */
407 {VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x1E}
408};
409
410#define NUM_TOTAL_K400_LCD_RES_10X7_1366X7 ARRAY_SIZE(K400_LCD_RES_10X7_1366X7)
411
412struct io_reg K400_LCD_RES_12X10_1366X7[] = {
413 /* 1280x768, 1280x960, 1280x1024 */
414 /* IGA2 Horizontal Total */
415 {VIACR, CR50, 0xFF, 0x97}, {VIACR, CR55, 0x0F, 0x56},
416 /* IGA2 Horizontal Blank End */
417 {VIACR, CR53, 0xFF, 0x97}, {VIACR, CR54, 0x38, 0x75},
418 {VIACR, CR5D, 0x40, 0x24},
419 /* IGA2 Horizontal Total Shadow */
420 {VIACR, CR6D, 0xFF, 0xCE}, {VIACR, CR71, 0x08, 0x44},
421 /* IGA2 Horizontal Blank End Shadow */
422 {VIACR, CR6E, 0xFF, 0xD2},
423 /* IGA2 Offset */
424 {VIACR, CR66, 0xFF, 0xC9}, {VIACR, CR67, 0x03, 0x04},
425 /* VCLK */
426 {VIASR, SR46, 0xFF, 0x84}, {VIASR, SR47, 0xFF, 0x79}
427};
428
429#define NUM_TOTAL_K400_LCD_RES_12X10_1366X7\
430 ARRAY_SIZE(K400_LCD_RES_12X10_1366X7)
431
432/* ++++++ K400 ++++++ */
433/* Panel 1280x1024 */
434struct io_reg K400_LCD_RES_6X4_12X10[] = {
435 /*IGA2 Horizontal Total */
436 {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x46},
437 /*IGA2 Horizontal Blank End */
438 {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x74},
439 {VIACR, CR5D, 0x40, 0x1C},
440 /*IGA2 Horizontal Total Shadow */
441 {VIACR, CR6D, 0xFF, 0x5F}, {VIACR, CR71, 0x08, 0x34},
442 /*IGA2 Horizontal Blank End Shadow */
443 {VIACR, CR6E, 0xFF, 0x63},
444 /*IGA2 Offset */
445 {VIACR, CR66, 0xFF, 0xAA}, {VIACR, CR67, 0x03, 0x00},
446 /*VCLK*/ {VIASR, SR46, 0xFF, 0x07}, {VIASR, SR47, 0xFF, 0x19}
447};
448
449#define NUM_TOTAL_K400_LCD_RES_6X4_12X10 ARRAY_SIZE(K400_LCD_RES_6X4_12X10)
450
451struct io_reg K400_LCD_RES_7X4_12X10[] = {
452 /*IGA2 Horizontal Total */
453 {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x46},
454 /*IGA2 Horizontal Blank End */
455 {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x74},
456 {VIACR, CR5D, 0x40, 0x1C},
457 /*IGA2 Horizontal Total Shadow */
458 {VIACR, CR6D, 0xFF, 0x68}, {VIACR, CR71, 0x08, 0x34},
459 /*IGA2 Horizontal Blank End Shadow */
460 {VIACR, CR6E, 0xFF, 0x6C},
461 /*IGA2 Offset */
462 {VIACR, CR66, 0xFF, 0xA8}, {VIACR, CR67, 0x03, 0x00},
463 /*VCLK*/ {VIASR, SR46, 0xFF, 0x87}, {VIASR, SR47, 0xFF, 0xED}
464};
465
466#define NUM_TOTAL_K400_LCD_RES_7X4_12X10 ARRAY_SIZE(K400_LCD_RES_7X4_12X10)
467
468struct io_reg K400_LCD_RES_8X6_12X10[] = {
469 /*IGA2 Horizontal Total */
470 {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x46},
471 /*IGA2 Horizontal Blank End */
472 {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x74},
473 {VIACR, CR5D, 0x40, 0x1C},
474 /*IGA2 Horizontal Total Shadow */
475 {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x34},
476 /*IGA2 Horizontal Blank End Shadow */
477 {VIACR, CR6E, 0xFF, 0x83},
478 /*IGA2 Offset */
479 {VIACR, CR66, 0xFF, 0xBE}, {VIACR, CR67, 0x03, 0x00},
480 /*VCLK*/ {VIASR, SR46, 0xFF, 0x07}, {VIASR, SR47, 0xFF, 0x21}
481};
482
483#define NUM_TOTAL_K400_LCD_RES_8X6_12X10 ARRAY_SIZE(K400_LCD_RES_8X6_12X10)
484
485struct io_reg K400_LCD_RES_10X7_12X10[] = {
486 /*IGA2 Horizontal Total */
487 {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x46},
488 /*IGA2 Horizontal Blank End */
489 {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x74},
490 {VIACR, CR5D, 0x40, 0x1C},
491 /*IGA2 Horizontal Total Shadow */
492 {VIACR, CR6D, 0xFF, 0xA3}, {VIACR, CR71, 0x08, 0x34},
493 /*IGA2 Horizontal Blank End Shadow */
494 {VIACR, CR6E, 0xFF, 0xA7},
495 /*IGA2 Offset */
496 {VIACR, CR66, 0xFF, 0xBE}, {VIACR, CR67, 0x03, 0x04},
497 /*VCLK*/ {VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x1E}
498};
499
500#define NUM_TOTAL_K400_LCD_RES_10X7_12X10 ARRAY_SIZE(K400_LCD_RES_10X7_12X10)
501
502/* ++++++ K400 ++++++ */
503/* Panel 1024x768 */
504struct io_reg K400_LCD_RES_6X4_10X7[] = {
505 /*IGA2 Horizontal Total */
506 {VIACR, CR50, 0xFF, 0x47}, {VIACR, CR55, 0x0F, 0x35},
507 /*IGA2 Horizontal Blank End */
508 {VIACR, CR53, 0xFF, 0x47}, {VIACR, CR54, 0x38, 0x2B},
509 {VIACR, CR5D, 0x40, 0x13},
510 /*IGA2 Horizontal Total Shadow */
511 {VIACR, CR6D, 0xFF, 0x60}, {VIACR, CR71, 0x08, 0x23},
512 /*IGA2 Horizontal Blank End Shadow */
513 {VIACR, CR6E, 0xFF, 0x64},
514 /*IGA2 Offset */
515 {VIACR, CR66, 0xFF, 0x8C}, {VIACR, CR67, 0x03, 0x00},
516 /*VCLK*/ {VIASR, SR46, 0xFF, 0x87}, {VIASR, SR47, 0xFF, 0x4C}
517};
518
519#define NUM_TOTAL_K400_LCD_RES_6X4_10X7 ARRAY_SIZE(K400_LCD_RES_6X4_10X7)
520
521struct io_reg K400_LCD_RES_7X4_10X7[] = {
522 /*IGA2 Horizontal Total */
523 {VIACR, CR50, 0xFF, 0x3B}, {VIACR, CR55, 0x0F, 0x35},
524 /*IGA2 Horizontal Blank End */
525 {VIACR, CR53, 0xFF, 0x3B}, {VIACR, CR54, 0x38, 0x2B},
526 {VIACR, CR5D, 0x40, 0x13},
527 /*IGA2 Horizontal Total Shadow */
528 {VIACR, CR6D, 0xFF, 0x71}, {VIACR, CR71, 0x08, 0x23},
529 /*IGA2 Horizontal Blank End Shadow */
530 {VIACR, CR6E, 0xFF, 0x75},
531 /*IGA2 Offset */
532 {VIACR, CR66, 0xFF, 0x96}, {VIACR, CR67, 0x03, 0x00},
533 /*VCLK*/ {VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x10}
534};
535
536#define NUM_TOTAL_K400_LCD_RES_7X4_10X7 ARRAY_SIZE(K400_LCD_RES_7X4_10X7)
537
538struct io_reg K400_LCD_RES_8X6_10X7[] = {
539 /*IGA2 Horizontal Total */
540 {VIACR, CR50, 0xFF, 0x37}, {VIACR, CR55, 0x0F, 0x35},
541 /*IGA2 Horizontal Blank End */
542 {VIACR, CR53, 0xFF, 0x37}, {VIACR, CR54, 0x38, 0x2B},
543 {VIACR, CR5D, 0x40, 0x13},
544 /*IGA2 Horizontal Total Shadow */
545 {VIACR, CR6D, 0xFF, 0x7E}, {VIACR, CR71, 0x08, 0x23},
546 /*IGA2 Horizontal Blank End Shadow */
547 {VIACR, CR6E, 0xFF, 0x82},
548 /*IGA2 Offset */
549 {VIACR, CR66, 0xFF, 0x8C}, {VIACR, CR67, 0x03, 0x00},
550 /*VCLK*/ {VIASR, SR46, 0xFF, 0x84}, {VIASR, SR47, 0xFF, 0xB9}
551};
552
553#define NUM_TOTAL_K400_LCD_RES_8X6_10X7 ARRAY_SIZE(K400_LCD_RES_8X6_10X7)
554
555/* ++++++ K400 ++++++ */
556/* Panel 800x600 */
557struct io_reg K400_LCD_RES_6X4_8X6[] = {
558 /*IGA2 Horizontal Total */
559 {VIACR, CR50, 0xFF, 0x1A}, {VIACR, CR55, 0x0F, 0x34},
560 /*IGA2 Horizontal Blank End */
561 {VIACR, CR53, 0xFF, 0x1A}, {VIACR, CR54, 0x38, 0xE3},
562 {VIACR, CR5D, 0x40, 0x12},
563 /*IGA2 Horizontal Total Shadow */
564 {VIACR, CR6D, 0xFF, 0x5F}, {VIACR, CR71, 0x08, 0x22},
565 /*IGA2 Horizontal Blank End Shadow */
566 {VIACR, CR6E, 0xFF, 0x63},
567 /*IGA2 Offset */
568 {VIACR, CR66, 0xFF, 0x6E}, {VIACR, CR67, 0x03, 0x00},
569 /*VCLK*/ {VIASR, SR46, 0xFF, 0x86}, {VIASR, SR47, 0xFF, 0xB3}
570};
571
572#define NUM_TOTAL_K400_LCD_RES_6X4_8X6 ARRAY_SIZE(K400_LCD_RES_6X4_8X6)
573
574struct io_reg K400_LCD_RES_7X4_8X6[] = {
575 /*IGA2 Horizontal Total */
576 {VIACR, CR50, 0xFF, 0x1F}, {VIACR, CR55, 0x0F, 0x34},
577 /*IGA2 Horizontal Blank End */
578 {VIACR, CR53, 0xFF, 0x1F}, {VIACR, CR54, 0x38, 0xE3},
579 {VIACR, CR5D, 0x40, 0x12},
580 /*IGA2 Horizontal Total Shadow */
581 {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x22},
582 /*IGA2 Horizontal Blank End Shadow */
583 {VIACR, CR6E, 0xFF, 0x83},
584 /*IGA2 Offset */
585 {VIACR, CR66, 0xFF, 0x78}, {VIACR, CR67, 0x03, 0x00},
586 /*VCLK*/ {VIASR, SR46, 0xFF, 0xC4}, {VIASR, SR47, 0xFF, 0x59}
587};
588
589#define NUM_TOTAL_K400_LCD_RES_7X4_8X6 ARRAY_SIZE(K400_LCD_RES_7X4_8X6)
590
591#endif /* __LCDTBL_H__ */
diff --git a/drivers/video/via/share.h b/drivers/video/via/share.h
new file mode 100644
index 000000000000..2e1254da9c8c
--- /dev/null
+++ b/drivers/video/via/share.h
@@ -0,0 +1,1105 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
14 * for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22#ifndef __SHARE_H__
23#define __SHARE_H__
24
25/* Define Return Value */
26#define FAIL -1
27#define OK 1
28
29#ifndef NULL
30#define NULL 0
31#endif
32
33/* Define Bit Field */
34#define BIT0 0x01
35#define BIT1 0x02
36#define BIT2 0x04
37#define BIT3 0x08
38#define BIT4 0x10
39#define BIT5 0x20
40#define BIT6 0x40
41#define BIT7 0x80
42
43/* Video Memory Size */
44#define VIDEO_MEMORY_SIZE_16M 0x1000000
45
46/* Definition Mode Index
47*/
48#define VIA_RES_640X480 0
49#define VIA_RES_800X600 1
50#define VIA_RES_1024X768 2
51#define VIA_RES_1152X864 3
52#define VIA_RES_1280X1024 4
53#define VIA_RES_1600X1200 5
54#define VIA_RES_1440X1050 6
55#define VIA_RES_1280X768 7
56#define VIA_RES_1280X960 8
57#define VIA_RES_1920X1440 9
58#define VIA_RES_848X480 10
59#define VIA_RES_1400X1050 11
60#define VIA_RES_720X480 12
61#define VIA_RES_720X576 13
62#define VIA_RES_1024X512 14
63#define VIA_RES_856X480 15
64#define VIA_RES_1024X576 16
65#define VIA_RES_640X400 17
66#define VIA_RES_1280X720 18
67#define VIA_RES_1920X1080 19
68#define VIA_RES_800X480 20
69#define VIA_RES_1368X768 21
70#define VIA_RES_1024X600 22
71#define VIA_RES_1280X800 23
72#define VIA_RES_1680X1050 24
73#define VIA_RES_960X600 25
74#define VIA_RES_1000X600 26
75#define VIA_RES_1088X612 27
76#define VIA_RES_1152X720 28
77#define VIA_RES_1200X720 29
78#define VIA_RES_1280X600 30
79#define VIA_RES_1360X768 31
80#define VIA_RES_1366X768 32
81#define VIA_RES_1440X900 33
82#define VIA_RES_1600X900 34
83#define VIA_RES_1600X1024 35
84#define VIA_RES_1792X1344 36
85#define VIA_RES_1856X1392 37
86#define VIA_RES_1920X1200 38
87#define VIA_RES_2048X1536 39
88#define VIA_RES_480X640 40
89
90/*Reduce Blanking*/
91#define VIA_RES_1360X768_RB 131
92#define VIA_RES_1440X900_RB 133
93#define VIA_RES_1400X1050_RB 111
94#define VIA_RES_1600X900_RB 134
95#define VIA_RES_1680X1050_RB 124
96#define VIA_RES_1920X1080_RB 119
97#define VIA_RES_1920X1200_RB 138
98
99#define VIA_RES_INVALID 255
100
101/* standard VGA IO port
102*/
103#define VIARMisc 0x3CC
104#define VIAWMisc 0x3C2
105#define VIAStatus 0x3DA
106#define VIACR 0x3D4
107#define VIASR 0x3C4
108#define VIAGR 0x3CE
109#define VIAAR 0x3C0
110
111#define StdCR 0x19
112#define StdSR 0x04
113#define StdGR 0x09
114#define StdAR 0x14
115
116#define PatchCR 11
117
118/* Display path */
119#define IGA1 1
120#define IGA2 2
121#define IGA1_IGA2 3
122
123/* Define Color Depth */
124#define MODE_8BPP 1
125#define MODE_16BPP 2
126#define MODE_32BPP 4
127
128#define GR20 0x20
129#define GR21 0x21
130#define GR22 0x22
131
132/* Sequencer Registers */
133#define SR01 0x01
134#define SR10 0x10
135#define SR12 0x12
136#define SR15 0x15
137#define SR16 0x16
138#define SR17 0x17
139#define SR18 0x18
140#define SR1B 0x1B
141#define SR1A 0x1A
142#define SR1C 0x1C
143#define SR1D 0x1D
144#define SR1E 0x1E
145#define SR1F 0x1F
146#define SR20 0x20
147#define SR21 0x21
148#define SR22 0x22
149#define SR2A 0x2A
150#define SR2D 0x2D
151#define SR2E 0x2E
152
153#define SR30 0x30
154#define SR39 0x39
155#define SR3D 0x3D
156#define SR3E 0x3E
157#define SR3F 0x3F
158#define SR40 0x40
159#define SR43 0x43
160#define SR44 0x44
161#define SR45 0x45
162#define SR46 0x46
163#define SR47 0x47
164#define SR48 0x48
165#define SR49 0x49
166#define SR4A 0x4A
167#define SR4B 0x4B
168#define SR4C 0x4C
169#define SR52 0x52
170#define SR5E 0x5E
171#define SR65 0x65
172
173/* CRT Controller Registers */
174#define CR00 0x00
175#define CR01 0x01
176#define CR02 0x02
177#define CR03 0x03
178#define CR04 0x04
179#define CR05 0x05
180#define CR06 0x06
181#define CR07 0x07
182#define CR08 0x08
183#define CR09 0x09
184#define CR0A 0x0A
185#define CR0B 0x0B
186#define CR0C 0x0C
187#define CR0D 0x0D
188#define CR0E 0x0E
189#define CR0F 0x0F
190#define CR10 0x10
191#define CR11 0x11
192#define CR12 0x12
193#define CR13 0x13
194#define CR14 0x14
195#define CR15 0x15
196#define CR16 0x16
197#define CR17 0x17
198#define CR18 0x18
199
200/* Extend CRT Controller Registers */
201#define CR30 0x30
202#define CR31 0x31
203#define CR32 0x32
204#define CR33 0x33
205#define CR34 0x34
206#define CR35 0x35
207#define CR36 0x36
208#define CR37 0x37
209#define CR38 0x38
210#define CR39 0x39
211#define CR3A 0x3A
212#define CR3B 0x3B
213#define CR3C 0x3C
214#define CR3D 0x3D
215#define CR3E 0x3E
216#define CR3F 0x3F
217#define CR40 0x40
218#define CR41 0x41
219#define CR42 0x42
220#define CR43 0x43
221#define CR44 0x44
222#define CR45 0x45
223#define CR46 0x46
224#define CR47 0x47
225#define CR48 0x48
226#define CR49 0x49
227#define CR4A 0x4A
228#define CR4B 0x4B
229#define CR4C 0x4C
230#define CR4D 0x4D
231#define CR4E 0x4E
232#define CR4F 0x4F
233#define CR50 0x50
234#define CR51 0x51
235#define CR52 0x52
236#define CR53 0x53
237#define CR54 0x54
238#define CR55 0x55
239#define CR56 0x56
240#define CR57 0x57
241#define CR58 0x58
242#define CR59 0x59
243#define CR5A 0x5A
244#define CR5B 0x5B
245#define CR5C 0x5C
246#define CR5D 0x5D
247#define CR5E 0x5E
248#define CR5F 0x5F
249#define CR60 0x60
250#define CR61 0x61
251#define CR62 0x62
252#define CR63 0x63
253#define CR64 0x64
254#define CR65 0x65
255#define CR66 0x66
256#define CR67 0x67
257#define CR68 0x68
258#define CR69 0x69
259#define CR6A 0x6A
260#define CR6B 0x6B
261#define CR6C 0x6C
262#define CR6D 0x6D
263#define CR6E 0x6E
264#define CR6F 0x6F
265#define CR70 0x70
266#define CR71 0x71
267#define CR72 0x72
268#define CR73 0x73
269#define CR74 0x74
270#define CR75 0x75
271#define CR76 0x76
272#define CR77 0x77
273#define CR78 0x78
274#define CR79 0x79
275#define CR7A 0x7A
276#define CR7B 0x7B
277#define CR7C 0x7C
278#define CR7D 0x7D
279#define CR7E 0x7E
280#define CR7F 0x7F
281#define CR80 0x80
282#define CR81 0x81
283#define CR82 0x82
284#define CR83 0x83
285#define CR84 0x84
286#define CR85 0x85
287#define CR86 0x86
288#define CR87 0x87
289#define CR88 0x88
290#define CR89 0x89
291#define CR8A 0x8A
292#define CR8B 0x8B
293#define CR8C 0x8C
294#define CR8D 0x8D
295#define CR8E 0x8E
296#define CR8F 0x8F
297#define CR90 0x90
298#define CR91 0x91
299#define CR92 0x92
300#define CR93 0x93
301#define CR94 0x94
302#define CR95 0x95
303#define CR96 0x96
304#define CR97 0x97
305#define CR98 0x98
306#define CR99 0x99
307#define CR9A 0x9A
308#define CR9B 0x9B
309#define CR9C 0x9C
310#define CR9D 0x9D
311#define CR9E 0x9E
312#define CR9F 0x9F
313#define CRA0 0xA0
314#define CRA1 0xA1
315#define CRA2 0xA2
316#define CRA3 0xA3
317#define CRD2 0xD2
318#define CRD3 0xD3
319#define CRD4 0xD4
320
321/* LUT Table*/
322#define LUT_DATA 0x3C9 /* DACDATA */
323#define LUT_INDEX_READ 0x3C7 /* DACRX */
324#define LUT_INDEX_WRITE 0x3C8 /* DACWX */
325#define DACMASK 0x3C6
326
327/* Definition Device */
328#define DEVICE_CRT 0x01
329#define DEVICE_DVI 0x03
330#define DEVICE_LCD 0x04
331
332/* Device output interface */
333#define INTERFACE_NONE 0x00
334#define INTERFACE_ANALOG_RGB 0x01
335#define INTERFACE_DVP0 0x02
336#define INTERFACE_DVP1 0x03
337#define INTERFACE_DFP_HIGH 0x04
338#define INTERFACE_DFP_LOW 0x05
339#define INTERFACE_DFP 0x06
340#define INTERFACE_LVDS0 0x07
341#define INTERFACE_LVDS1 0x08
342#define INTERFACE_LVDS0LVDS1 0x09
343#define INTERFACE_TMDS 0x0A
344
345#define HW_LAYOUT_LCD_ONLY 0x01
346#define HW_LAYOUT_DVI_ONLY 0x02
347#define HW_LAYOUT_LCD_DVI 0x03
348#define HW_LAYOUT_LCD1_LCD2 0x04
349#define HW_LAYOUT_LCD_EXTERNAL_LCD2 0x10
350
351/* Definition Refresh Rate */
352#define REFRESH_50 50
353#define REFRESH_60 60
354#define REFRESH_75 75
355#define REFRESH_85 85
356#define REFRESH_100 100
357#define REFRESH_120 120
358
359/* Definition Sync Polarity*/
360#define NEGATIVE 1
361#define POSITIVE 0
362
363/*480x640@60 Sync Polarity (GTF)
364*/
365#define M480X640_R60_HSP NEGATIVE
366#define M480X640_R60_VSP POSITIVE
367
368/*640x480@60 Sync Polarity (VESA Mode)
369*/
370#define M640X480_R60_HSP NEGATIVE
371#define M640X480_R60_VSP NEGATIVE
372
373/*640x480@75 Sync Polarity (VESA Mode)
374*/
375#define M640X480_R75_HSP NEGATIVE
376#define M640X480_R75_VSP NEGATIVE
377
378/*640x480@85 Sync Polarity (VESA Mode)
379*/
380#define M640X480_R85_HSP NEGATIVE
381#define M640X480_R85_VSP NEGATIVE
382
383/*640x480@100 Sync Polarity (GTF Mode)
384*/
385#define M640X480_R100_HSP NEGATIVE
386#define M640X480_R100_VSP POSITIVE
387
388/*640x480@120 Sync Polarity (GTF Mode)
389*/
390#define M640X480_R120_HSP NEGATIVE
391#define M640X480_R120_VSP POSITIVE
392
393/*720x480@60 Sync Polarity (GTF Mode)
394*/
395#define M720X480_R60_HSP NEGATIVE
396#define M720X480_R60_VSP POSITIVE
397
398/*720x576@60 Sync Polarity (GTF Mode)
399*/
400#define M720X576_R60_HSP NEGATIVE
401#define M720X576_R60_VSP POSITIVE
402
403/*800x600@60 Sync Polarity (VESA Mode)
404*/
405#define M800X600_R60_HSP POSITIVE
406#define M800X600_R60_VSP POSITIVE
407
408/*800x600@75 Sync Polarity (VESA Mode)
409*/
410#define M800X600_R75_HSP POSITIVE
411#define M800X600_R75_VSP POSITIVE
412
413/*800x600@85 Sync Polarity (VESA Mode)
414*/
415#define M800X600_R85_HSP POSITIVE
416#define M800X600_R85_VSP POSITIVE
417
418/*800x600@100 Sync Polarity (GTF Mode)
419*/
420#define M800X600_R100_HSP NEGATIVE
421#define M800X600_R100_VSP POSITIVE
422
423/*800x600@120 Sync Polarity (GTF Mode)
424*/
425#define M800X600_R120_HSP NEGATIVE
426#define M800X600_R120_VSP POSITIVE
427
428/*800x480@60 Sync Polarity (CVT Mode)
429*/
430#define M800X480_R60_HSP NEGATIVE
431#define M800X480_R60_VSP POSITIVE
432
433/*848x480@60 Sync Polarity (CVT Mode)
434*/
435#define M848X480_R60_HSP NEGATIVE
436#define M848X480_R60_VSP POSITIVE
437
438/*852x480@60 Sync Polarity (GTF Mode)
439*/
440#define M852X480_R60_HSP NEGATIVE
441#define M852X480_R60_VSP POSITIVE
442
443/*1024x512@60 Sync Polarity (GTF Mode)
444*/
445#define M1024X512_R60_HSP NEGATIVE
446#define M1024X512_R60_VSP POSITIVE
447
448/*1024x600@60 Sync Polarity (GTF Mode)
449*/
450#define M1024X600_R60_HSP NEGATIVE
451#define M1024X600_R60_VSP POSITIVE
452
453/*1024x768@60 Sync Polarity (VESA Mode)
454*/
455#define M1024X768_R60_HSP NEGATIVE
456#define M1024X768_R60_VSP NEGATIVE
457
458/*1024x768@75 Sync Polarity (VESA Mode)
459*/
460#define M1024X768_R75_HSP POSITIVE
461#define M1024X768_R75_VSP POSITIVE
462
463/*1024x768@85 Sync Polarity (VESA Mode)
464*/
465#define M1024X768_R85_HSP POSITIVE
466#define M1024X768_R85_VSP POSITIVE
467
468/*1024x768@100 Sync Polarity (GTF Mode)
469*/
470#define M1024X768_R100_HSP NEGATIVE
471#define M1024X768_R100_VSP POSITIVE
472
473/*1152x864@75 Sync Polarity (VESA Mode)
474*/
475#define M1152X864_R75_HSP POSITIVE
476#define M1152X864_R75_VSP POSITIVE
477
478/*1280x720@60 Sync Polarity (GTF Mode)
479*/
480#define M1280X720_R60_HSP NEGATIVE
481#define M1280X720_R60_VSP POSITIVE
482
483/* 1280x768@50 Sync Polarity (GTF Mode) */
484#define M1280X768_R50_HSP NEGATIVE
485#define M1280X768_R50_VSP POSITIVE
486
487/*1280x768@60 Sync Polarity (GTF Mode)
488*/
489#define M1280X768_R60_HSP NEGATIVE
490#define M1280X768_R60_VSP POSITIVE
491
492/*1280x800@60 Sync Polarity (CVT Mode)
493*/
494#define M1280X800_R60_HSP NEGATIVE
495#define M1280X800_R60_VSP POSITIVE
496
497/*1280x960@60 Sync Polarity (VESA Mode)
498*/
499#define M1280X960_R60_HSP POSITIVE
500#define M1280X960_R60_VSP POSITIVE
501
502/*1280x1024@60 Sync Polarity (VESA Mode)
503*/
504#define M1280X1024_R60_HSP POSITIVE
505#define M1280X1024_R60_VSP POSITIVE
506
507/* 1360x768@60 Sync Polarity (CVT Mode) */
508#define M1360X768_R60_HSP POSITIVE
509#define M1360X768_R60_VSP POSITIVE
510
511/* 1360x768@60 Sync Polarity (CVT Reduce Blanking Mode) */
512#define M1360X768_RB_R60_HSP POSITIVE
513#define M1360X768_RB_R60_VSP NEGATIVE
514
515/* 1368x768@50 Sync Polarity (GTF Mode) */
516#define M1368X768_R50_HSP NEGATIVE
517#define M1368X768_R50_VSP POSITIVE
518
519/* 1368x768@60 Sync Polarity (VESA Mode) */
520#define M1368X768_R60_HSP NEGATIVE
521#define M1368X768_R60_VSP POSITIVE
522
523/*1280x1024@75 Sync Polarity (VESA Mode)
524*/
525#define M1280X1024_R75_HSP POSITIVE
526#define M1280X1024_R75_VSP POSITIVE
527
528/*1280x1024@85 Sync Polarity (VESA Mode)
529*/
530#define M1280X1024_R85_HSP POSITIVE
531#define M1280X1024_R85_VSP POSITIVE
532
533/*1440x1050@60 Sync Polarity (GTF Mode)
534*/
535#define M1440X1050_R60_HSP NEGATIVE
536#define M1440X1050_R60_VSP POSITIVE
537
538/*1600x1200@60 Sync Polarity (VESA Mode)
539*/
540#define M1600X1200_R60_HSP POSITIVE
541#define M1600X1200_R60_VSP POSITIVE
542
543/*1600x1200@75 Sync Polarity (VESA Mode)
544*/
545#define M1600X1200_R75_HSP POSITIVE
546#define M1600X1200_R75_VSP POSITIVE
547
548/* 1680x1050@60 Sync Polarity (CVT Mode) */
549#define M1680x1050_R60_HSP NEGATIVE
550#define M1680x1050_R60_VSP NEGATIVE
551
552/* 1680x1050@60 Sync Polarity (CVT Reduce Blanking Mode) */
553#define M1680x1050_RB_R60_HSP POSITIVE
554#define M1680x1050_RB_R60_VSP NEGATIVE
555
556/* 1680x1050@75 Sync Polarity (CVT Mode) */
557#define M1680x1050_R75_HSP NEGATIVE
558#define M1680x1050_R75_VSP POSITIVE
559
560/*1920x1080@60 Sync Polarity (CVT Mode)
561*/
562#define M1920X1080_R60_HSP NEGATIVE
563#define M1920X1080_R60_VSP POSITIVE
564
565/* 1920x1080@60 Sync Polarity (CVT Reduce Blanking Mode) */
566#define M1920X1080_RB_R60_HSP POSITIVE
567#define M1920X1080_RB_R60_VSP NEGATIVE
568
569/*1920x1440@60 Sync Polarity (VESA Mode)
570*/
571#define M1920X1440_R60_HSP NEGATIVE
572#define M1920X1440_R60_VSP POSITIVE
573
574/*1920x1440@75 Sync Polarity (VESA Mode)
575*/
576#define M1920X1440_R75_HSP NEGATIVE
577#define M1920X1440_R75_VSP POSITIVE
578
579#if 0
580/* 1400x1050@60 Sync Polarity (VESA Mode) */
581#define M1400X1050_R60_HSP NEGATIVE
582#define M1400X1050_R60_VSP NEGATIVE
583#endif
584
585/* 1400x1050@60 Sync Polarity (CVT Mode) */
586#define M1400X1050_R60_HSP NEGATIVE
587#define M1400X1050_R60_VSP POSITIVE
588
589/* 1400x1050@60 Sync Polarity (CVT Reduce Blanking Mode) */
590#define M1400X1050_RB_R60_HSP POSITIVE
591#define M1400X1050_RB_R60_VSP NEGATIVE
592
593/* 1400x1050@75 Sync Polarity (CVT Mode) */
594#define M1400X1050_R75_HSP NEGATIVE
595#define M1400X1050_R75_VSP POSITIVE
596
597/* 960x600@60 Sync Polarity (CVT Mode) */
598#define M960X600_R60_HSP NEGATIVE
599#define M960X600_R60_VSP POSITIVE
600
601/* 1000x600@60 Sync Polarity (GTF Mode) */
602#define M1000X600_R60_HSP NEGATIVE
603#define M1000X600_R60_VSP POSITIVE
604
605/* 1024x576@60 Sync Polarity (GTF Mode) */
606#define M1024X576_R60_HSP NEGATIVE
607#define M1024X576_R60_VSP POSITIVE
608
609/*1024x600@60 Sync Polarity (GTF Mode)*/
610#define M1024X600_R60_HSP NEGATIVE
611#define M1024X600_R60_VSP POSITIVE
612
613/* 1088x612@60 Sync Polarity (CVT Mode) */
614#define M1088X612_R60_HSP NEGATIVE
615#define M1088X612_R60_VSP POSITIVE
616
617/* 1152x720@60 Sync Polarity (CVT Mode) */
618#define M1152X720_R60_HSP NEGATIVE
619#define M1152X720_R60_VSP POSITIVE
620
621/* 1200x720@60 Sync Polarity (GTF Mode) */
622#define M1200X720_R60_HSP NEGATIVE
623#define M1200X720_R60_VSP POSITIVE
624
625/* 1280x600@60 Sync Polarity (GTF Mode) */
626#define M1280x600_R60_HSP NEGATIVE
627#define M1280x600_R60_VSP POSITIVE
628
629/* 1280x720@50 Sync Polarity (GTF Mode) */
630#define M1280X720_R50_HSP NEGATIVE
631#define M1280X720_R50_VSP POSITIVE
632
633/* 1280x720@60 Sync Polarity (CEA Mode) */
634#define M1280X720_CEA_R60_HSP POSITIVE
635#define M1280X720_CEA_R60_VSP POSITIVE
636
637/* 1440x900@60 Sync Polarity (CVT Mode) */
638#define M1440X900_R60_HSP NEGATIVE
639#define M1440X900_R60_VSP POSITIVE
640
641/* 1440x900@75 Sync Polarity (CVT Mode) */
642#define M1440X900_R75_HSP NEGATIVE
643#define M1440X900_R75_VSP POSITIVE
644
645/* 1440x900@60 Sync Polarity (CVT Reduce Blanking Mode) */
646#define M1440X900_RB_R60_HSP POSITIVE
647#define M1440X900_RB_R60_VSP NEGATIVE
648
649/* 1600x900@60 Sync Polarity (CVT Mode) */
650#define M1600X900_R60_HSP NEGATIVE
651#define M1600X900_R60_VSP POSITIVE
652
653/* 1600x900@60 Sync Polarity (CVT Reduce Blanking Mode) */
654#define M1600X900_RB_R60_HSP POSITIVE
655#define M1600X900_RB_R60_VSP NEGATIVE
656
657/* 1600x1024@60 Sync Polarity (GTF Mode) */
658#define M1600X1024_R60_HSP NEGATIVE
659#define M1600X1024_R60_VSP POSITIVE
660
661/* 1792x1344@60 Sync Polarity (DMT Mode) */
662#define M1792x1344_R60_HSP NEGATIVE
663#define M1792x1344_R60_VSP POSITIVE
664
665/* 1856x1392@60 Sync Polarity (DMT Mode) */
666#define M1856x1392_R60_HSP NEGATIVE
667#define M1856x1392_R60_VSP POSITIVE
668
669/* 1920x1200@60 Sync Polarity (CVT Mode) */
670#define M1920X1200_R60_HSP NEGATIVE
671#define M1920X1200_R60_VSP POSITIVE
672
673/* 1920x1200@60 Sync Polarity (CVT Reduce Blanking Mode) */
674#define M1920X1200_RB_R60_HSP POSITIVE
675#define M1920X1200_RB_R60_VSP NEGATIVE
676
677/* 1920x1080@60 Sync Polarity (CEA Mode) */
678#define M1920X1080_CEA_R60_HSP POSITIVE
679#define M1920X1080_CEA_R60_VSP POSITIVE
680
681/* 2048x1536@60 Sync Polarity (CVT Mode) */
682#define M2048x1536_R60_HSP NEGATIVE
683#define M2048x1536_R60_VSP POSITIVE
684
685/* define PLL index: */
686#define CLK_25_175M 25175000
687#define CLK_26_880M 26880000
688#define CLK_29_581M 29581000
689#define CLK_31_490M 31490000
690#define CLK_31_500M 31500000
691#define CLK_31_728M 31728000
692#define CLK_32_668M 32688000
693#define CLK_36_000M 36000000
694#define CLK_40_000M 40000000
695#define CLK_41_291M 41291000
696#define CLK_43_163M 43163000
697#define CLK_45_250M 45250000 /* 45.46MHz */
698#define CLK_46_000M 46000000
699#define CLK_46_996M 46996000
700#define CLK_48_000M 48000000
701#define CLK_48_875M 48875000
702#define CLK_49_500M 49500000
703#define CLK_52_406M 52406000
704#define CLK_52_977M 52977000
705#define CLK_56_250M 56250000
706#define CLK_60_466M 60466000
707#define CLK_61_500M 61500000
708#define CLK_65_000M 65000000
709#define CLK_65_178M 65178000
710#define CLK_66_750M 66750000 /* 67.116MHz */
711#define CLK_68_179M 68179000
712#define CLK_69_924M 69924000
713#define CLK_70_159M 70159000
714#define CLK_72_000M 72000000
715#define CLK_74_270M 74270000
716#define CLK_78_750M 78750000
717#define CLK_80_136M 80136000
718#define CLK_83_375M 83375000
719#define CLK_83_950M 83950000
720#define CLK_84_750M 84750000 /* 84.537Mhz */
721#define CLK_85_860M 85860000
722#define CLK_88_750M 88750000
723#define CLK_94_500M 94500000
724#define CLK_97_750M 97750000
725#define CLK_101_000M 101000000
726#define CLK_106_500M 106500000
727#define CLK_108_000M 108000000
728#define CLK_113_309M 113309000
729#define CLK_118_840M 118840000
730#define CLK_119_000M 119000000
731#define CLK_121_750M 121750000 /* 121.704MHz */
732#define CLK_125_104M 125104000
733#define CLK_133_308M 133308000
734#define CLK_135_000M 135000000
735#define CLK_136_700M 136700000
736#define CLK_138_400M 138400000
737#define CLK_146_760M 146760000
738#define CLK_148_500M 148500000
739
740#define CLK_153_920M 153920000
741#define CLK_156_000M 156000000
742#define CLK_157_500M 157500000
743#define CLK_162_000M 162000000
744#define CLK_187_000M 187000000
745#define CLK_193_295M 193295000
746#define CLK_202_500M 202500000
747#define CLK_204_000M 204000000
748#define CLK_218_500M 218500000
749#define CLK_234_000M 234000000
750#define CLK_267_250M 267250000
751#define CLK_297_500M 297500000
752#define CLK_74_481M 74481000
753#define CLK_172_798M 172798000
754#define CLK_122_614M 122614000
755
756/* CLE266 PLL value
757*/
758#define CLE266_PLL_25_175M 0x0000C763
759#define CLE266_PLL_26_880M 0x0000440F
760#define CLE266_PLL_29_581M 0x00008421
761#define CLE266_PLL_31_490M 0x00004721
762#define CLE266_PLL_31_500M 0x0000C3B5
763#define CLE266_PLL_31_728M 0x0000471F
764#define CLE266_PLL_32_668M 0x0000C449
765#define CLE266_PLL_36_000M 0x0000C5E5
766#define CLE266_PLL_40_000M 0x0000C459
767#define CLE266_PLL_41_291M 0x00004417
768#define CLE266_PLL_43_163M 0x0000C579
769#define CLE266_PLL_45_250M 0x0000C57F /* 45.46MHz */
770#define CLE266_PLL_46_000M 0x0000875A
771#define CLE266_PLL_46_996M 0x0000C4E9
772#define CLE266_PLL_48_000M 0x00001443
773#define CLE266_PLL_48_875M 0x00001D63
774#define CLE266_PLL_49_500M 0x00008653
775#define CLE266_PLL_52_406M 0x0000C475
776#define CLE266_PLL_52_977M 0x00004525
777#define CLE266_PLL_56_250M 0x000047B7
778#define CLE266_PLL_60_466M 0x0000494C
779#define CLE266_PLL_61_500M 0x00001456
780#define CLE266_PLL_65_000M 0x000086ED
781#define CLE266_PLL_65_178M 0x0000855B
782#define CLE266_PLL_66_750M 0x0000844B /* 67.116MHz */
783#define CLE266_PLL_68_179M 0x00000413
784#define CLE266_PLL_69_924M 0x00001153
785#define CLE266_PLL_70_159M 0x00001462
786#define CLE266_PLL_72_000M 0x00001879
787#define CLE266_PLL_74_270M 0x00004853
788#define CLE266_PLL_78_750M 0x00004321
789#define CLE266_PLL_80_136M 0x0000051C
790#define CLE266_PLL_83_375M 0x0000C25D
791#define CLE266_PLL_83_950M 0x00000729
792#define CLE266_PLL_84_750M 0x00008576 /* 84.537MHz */
793#define CLE266_PLL_85_860M 0x00004754
794#define CLE266_PLL_88_750M 0x0000051F
795#define CLE266_PLL_94_500M 0x00000521
796#define CLE266_PLL_97_750M 0x00004652
797#define CLE266_PLL_101_000M 0x0000497F
798#define CLE266_PLL_106_500M 0x00008477 /* 106.491463 MHz */
799#define CLE266_PLL_108_000M 0x00008479
800#define CLE266_PLL_113_309M 0x00000C5F
801#define CLE266_PLL_118_840M 0x00004553
802#define CLE266_PLL_119_000M 0x00000D6C
803#define CLE266_PLL_121_750M 0x00004555 /* 121.704MHz */
804#define CLE266_PLL_125_104M 0x000006B5
805#define CLE266_PLL_133_308M 0x0000465F
806#define CLE266_PLL_135_000M 0x0000455E
807#define CLE266_PLL_136_700M 0x00000C73
808#define CLE266_PLL_138_400M 0x00000957
809#define CLE266_PLL_146_760M 0x00004567
810#define CLE266_PLL_148_500M 0x00000853
811#define CLE266_PLL_153_920M 0x00000856
812#define CLE266_PLL_156_000M 0x0000456D
813#define CLE266_PLL_157_500M 0x000005B7
814#define CLE266_PLL_162_000M 0x00004571
815#define CLE266_PLL_187_000M 0x00000976
816#define CLE266_PLL_193_295M 0x0000086C
817#define CLE266_PLL_202_500M 0x00000763
818#define CLE266_PLL_204_000M 0x00000764
819#define CLE266_PLL_218_500M 0x0000065C
820#define CLE266_PLL_234_000M 0x00000662
821#define CLE266_PLL_267_250M 0x00000670
822#define CLE266_PLL_297_500M 0x000005E6
823#define CLE266_PLL_74_481M 0x0000051A
824#define CLE266_PLL_172_798M 0x00004579
825#define CLE266_PLL_122_614M 0x0000073C
826
827/* K800 PLL value
828*/
829#define K800_PLL_25_175M 0x00539001
830#define K800_PLL_26_880M 0x001C8C80
831#define K800_PLL_29_581M 0x00409080
832#define K800_PLL_31_490M 0x006F9001
833#define K800_PLL_31_500M 0x008B9002
834#define K800_PLL_31_728M 0x00AF9003
835#define K800_PLL_32_668M 0x00909002
836#define K800_PLL_36_000M 0x009F9002
837#define K800_PLL_40_000M 0x00578C02
838#define K800_PLL_41_291M 0x00438C01
839#define K800_PLL_43_163M 0x00778C03
840#define K800_PLL_45_250M 0x007D8C83 /* 45.46MHz */
841#define K800_PLL_46_000M 0x00658C02
842#define K800_PLL_46_996M 0x00818C83
843#define K800_PLL_48_000M 0x00848C83
844#define K800_PLL_48_875M 0x00508C81
845#define K800_PLL_49_500M 0x00518C01
846#define K800_PLL_52_406M 0x00738C02
847#define K800_PLL_52_977M 0x00928C83
848#define K800_PLL_56_250M 0x007C8C02
849#define K800_PLL_60_466M 0x00A78C83
850#define K800_PLL_61_500M 0x00AA8C83
851#define K800_PLL_65_000M 0x006B8C01
852#define K800_PLL_65_178M 0x00B48C83
853#define K800_PLL_66_750M 0x00948C82 /* 67.116MHz */
854#define K800_PLL_68_179M 0x00708C01
855#define K800_PLL_69_924M 0x00C18C83
856#define K800_PLL_70_159M 0x00C28C83
857#define K800_PLL_72_000M 0x009F8C82
858#define K800_PLL_74_270M 0x00ce0c03
859#define K800_PLL_78_750M 0x00408801
860#define K800_PLL_80_136M 0x00428801
861#define K800_PLL_83_375M 0x005B0882
862#define K800_PLL_83_950M 0x00738803
863#define K800_PLL_84_750M 0x00748883 /* 84.477MHz */
864#define K800_PLL_85_860M 0x00768883
865#define K800_PLL_88_750M 0x007A8883
866#define K800_PLL_94_500M 0x00828803
867#define K800_PLL_97_750M 0x00878883
868#define K800_PLL_101_000M 0x008B8883
869#define K800_PLL_106_500M 0x00758882 /* 106.491463 MHz */
870#define K800_PLL_108_000M 0x00778882
871#define K800_PLL_113_309M 0x005D8881
872#define K800_PLL_118_840M 0x00A48883
873#define K800_PLL_119_000M 0x00838882
874#define K800_PLL_121_750M 0x00A88883 /* 121.704MHz */
875#define K800_PLL_125_104M 0x00688801
876#define K800_PLL_133_308M 0x005D8801
877#define K800_PLL_135_000M 0x001A4081
878#define K800_PLL_136_700M 0x00BD8883
879#define K800_PLL_138_400M 0x00728881
880#define K800_PLL_146_760M 0x00CC8883
881#define K800_PLL_148_500M 0x00ce0803
882#define K800_PLL_153_920M 0x00548482
883#define K800_PLL_156_000M 0x006B8483
884#define K800_PLL_157_500M 0x00142080
885#define K800_PLL_162_000M 0x006F8483
886#define K800_PLL_187_000M 0x00818483
887#define K800_PLL_193_295M 0x004F8481
888#define K800_PLL_202_500M 0x00538481
889#define K800_PLL_204_000M 0x008D8483
890#define K800_PLL_218_500M 0x00978483
891#define K800_PLL_234_000M 0x00608401
892#define K800_PLL_267_250M 0x006E8481
893#define K800_PLL_297_500M 0x00A48402
894#define K800_PLL_74_481M 0x007B8C81
895#define K800_PLL_172_798M 0x00778483
896#define K800_PLL_122_614M 0x00878882
897
898/* PLL for VT3324 */
899#define CX700_25_175M 0x008B1003
900#define CX700_26_719M 0x00931003
901#define CX700_26_880M 0x00941003
902#define CX700_29_581M 0x00A49003
903#define CX700_31_490M 0x00AE1003
904#define CX700_31_500M 0x00AE1003
905#define CX700_31_728M 0x00AF1003
906#define CX700_32_668M 0x00B51003
907#define CX700_36_000M 0x00C81003
908#define CX700_40_000M 0x006E0C03
909#define CX700_41_291M 0x00710C03
910#define CX700_43_163M 0x00770C03
911#define CX700_45_250M 0x007D0C03 /* 45.46MHz */
912#define CX700_46_000M 0x007F0C03
913#define CX700_46_996M 0x00818C83
914#define CX700_48_000M 0x00840C03
915#define CX700_48_875M 0x00508C81
916#define CX700_49_500M 0x00880C03
917#define CX700_52_406M 0x00730C02
918#define CX700_52_977M 0x00920C03
919#define CX700_56_250M 0x009B0C03
920#define CX700_60_466M 0x00460C00
921#define CX700_61_500M 0x00AA0C03
922#define CX700_65_000M 0x006B0C01
923#define CX700_65_178M 0x006B0C01
924#define CX700_66_750M 0x00940C02 /*67.116MHz */
925#define CX700_68_179M 0x00BC0C03
926#define CX700_69_924M 0x00C10C03
927#define CX700_70_159M 0x00C20C03
928#define CX700_72_000M 0x009F0C02
929#define CX700_74_270M 0x00CE0C03
930#define CX700_74_481M 0x00CE0C03
931#define CX700_78_750M 0x006C0803
932#define CX700_80_136M 0x006E0803
933#define CX700_83_375M 0x005B0882
934#define CX700_83_950M 0x00730803
935#define CX700_84_750M 0x00740803 /* 84.537Mhz */
936#define CX700_85_860M 0x00760803
937#define CX700_88_750M 0x00AC8885
938#define CX700_94_500M 0x00820803
939#define CX700_97_750M 0x00870803
940#define CX700_101_000M 0x008B0803
941#define CX700_106_500M 0x00750802
942#define CX700_108_000M 0x00950803
943#define CX700_113_309M 0x005D0801
944#define CX700_118_840M 0x00A40803
945#define CX700_119_000M 0x00830802
946#define CX700_121_750M 0x00420800 /* 121.704MHz */
947#define CX700_125_104M 0x00AD0803
948#define CX700_133_308M 0x00930802
949#define CX700_135_000M 0x00950802
950#define CX700_136_700M 0x00BD0803
951#define CX700_138_400M 0x00720801
952#define CX700_146_760M 0x00CC0803
953#define CX700_148_500M 0x00a40802
954#define CX700_153_920M 0x00540402
955#define CX700_156_000M 0x006B0403
956#define CX700_157_500M 0x006C0403
957#define CX700_162_000M 0x006F0403
958#define CX700_172_798M 0x00770403
959#define CX700_187_000M 0x00810403
960#define CX700_193_295M 0x00850403
961#define CX700_202_500M 0x008C0403
962#define CX700_204_000M 0x008D0403
963#define CX700_218_500M 0x00970403
964#define CX700_234_000M 0x00600401
965#define CX700_267_250M 0x00B90403
966#define CX700_297_500M 0x00CE0403
967#define CX700_122_614M 0x00870802
968
969/* Definition CRTC Timing Index */
970#define H_TOTAL_INDEX 0
971#define H_ADDR_INDEX 1
972#define H_BLANK_START_INDEX 2
973#define H_BLANK_END_INDEX 3
974#define H_SYNC_START_INDEX 4
975#define H_SYNC_END_INDEX 5
976#define V_TOTAL_INDEX 6
977#define V_ADDR_INDEX 7
978#define V_BLANK_START_INDEX 8
979#define V_BLANK_END_INDEX 9
980#define V_SYNC_START_INDEX 10
981#define V_SYNC_END_INDEX 11
982#define H_TOTAL_SHADOW_INDEX 12
983#define H_BLANK_END_SHADOW_INDEX 13
984#define V_TOTAL_SHADOW_INDEX 14
985#define V_ADDR_SHADOW_INDEX 15
986#define V_BLANK_SATRT_SHADOW_INDEX 16
987#define V_BLANK_END_SHADOW_INDEX 17
988#define V_SYNC_SATRT_SHADOW_INDEX 18
989#define V_SYNC_END_SHADOW_INDEX 19
990
991/* Definition Video Mode Pixel Clock (picoseconds)
992*/
993#define RES_480X640_60HZ_PIXCLOCK 39722
994#define RES_640X480_60HZ_PIXCLOCK 39722
995#define RES_640X480_75HZ_PIXCLOCK 31747
996#define RES_640X480_85HZ_PIXCLOCK 27777
997#define RES_640X480_100HZ_PIXCLOCK 23168
998#define RES_640X480_120HZ_PIXCLOCK 19081
999#define RES_720X480_60HZ_PIXCLOCK 37020
1000#define RES_720X576_60HZ_PIXCLOCK 30611
1001#define RES_800X600_60HZ_PIXCLOCK 25000
1002#define RES_800X600_75HZ_PIXCLOCK 20203
1003#define RES_800X600_85HZ_PIXCLOCK 17777
1004#define RES_800X600_100HZ_PIXCLOCK 14667
1005#define RES_800X600_120HZ_PIXCLOCK 11912
1006#define RES_800X480_60HZ_PIXCLOCK 33805
1007#define RES_848X480_60HZ_PIXCLOCK 31756
1008#define RES_856X480_60HZ_PIXCLOCK 31518
1009#define RES_1024X512_60HZ_PIXCLOCK 24218
1010#define RES_1024X600_60HZ_PIXCLOCK 20460
1011#define RES_1024X768_60HZ_PIXCLOCK 15385
1012#define RES_1024X768_75HZ_PIXCLOCK 12699
1013#define RES_1024X768_85HZ_PIXCLOCK 10582
1014#define RES_1024X768_100HZ_PIXCLOCK 8825
1015#define RES_1152X864_75HZ_PIXCLOCK 9259
1016#define RES_1280X768_60HZ_PIXCLOCK 12480
1017#define RES_1280X800_60HZ_PIXCLOCK 11994
1018#define RES_1280X960_60HZ_PIXCLOCK 9259
1019#define RES_1280X1024_60HZ_PIXCLOCK 9260
1020#define RES_1280X1024_75HZ_PIXCLOCK 7408
1021#define RES_1280X768_85HZ_PIXCLOCK 6349
1022#define RES_1440X1050_60HZ_PIXCLOCK 7993
1023#define RES_1600X1200_60HZ_PIXCLOCK 6172
1024#define RES_1600X1200_75HZ_PIXCLOCK 4938
1025#define RES_1280X720_60HZ_PIXCLOCK 13426
1026#define RES_1920X1080_60HZ_PIXCLOCK 5787
1027#define RES_1400X1050_60HZ_PIXCLOCK 8214
1028#define RES_1400X1050_75HZ_PIXCLOCK 6410
1029#define RES_1368X768_60HZ_PIXCLOCK 11647
1030#define RES_960X600_60HZ_PIXCLOCK 22099
1031#define RES_1000X600_60HZ_PIXCLOCK 20834
1032#define RES_1024X576_60HZ_PIXCLOCK 21278
1033#define RES_1088X612_60HZ_PIXCLOCK 18877
1034#define RES_1152X720_60HZ_PIXCLOCK 14981
1035#define RES_1200X720_60HZ_PIXCLOCK 14253
1036#define RES_1280X600_60HZ_PIXCLOCK 16260
1037#define RES_1280X720_50HZ_PIXCLOCK 16538
1038#define RES_1280X768_50HZ_PIXCLOCK 15342
1039#define RES_1366X768_50HZ_PIXCLOCK 14301
1040#define RES_1366X768_60HZ_PIXCLOCK 11646
1041#define RES_1360X768_60HZ_PIXCLOCK 11799
1042#define RES_1440X900_60HZ_PIXCLOCK 9390
1043#define RES_1440X900_75HZ_PIXCLOCK 7315
1044#define RES_1600X900_60HZ_PIXCLOCK 8415
1045#define RES_1600X1024_60HZ_PIXCLOCK 7315
1046#define RES_1680X1050_60HZ_PIXCLOCK 6814
1047#define RES_1680X1050_75HZ_PIXCLOCK 5348
1048#define RES_1792X1344_60HZ_PIXCLOCK 4902
1049#define RES_1856X1392_60HZ_PIXCLOCK 4577
1050#define RES_1920X1200_60HZ_PIXCLOCK 5173
1051#define RES_1920X1440_60HZ_PIXCLOCK 4274
1052#define RES_1920X1440_75HZ_PIXCLOCK 3367
1053#define RES_2048X1536_60HZ_PIXCLOCK 3742
1054
1055#define RES_1360X768_RB_60HZ_PIXCLOCK 13889
1056#define RES_1400X1050_RB_60HZ_PIXCLOCK 9901
1057#define RES_1440X900_RB_60HZ_PIXCLOCK 11268
1058#define RES_1600X900_RB_60HZ_PIXCLOCK 10230
1059#define RES_1680X1050_RB_60HZ_PIXCLOCK 8403
1060#define RES_1920X1080_RB_60HZ_PIXCLOCK 7225
1061#define RES_1920X1200_RB_60HZ_PIXCLOCK 6497
1062
1063/* LCD display method
1064*/
1065#define LCD_EXPANDSION 0x00
1066#define LCD_CENTERING 0x01
1067
1068/* LCD mode
1069*/
1070#define LCD_OPENLDI 0x00
1071#define LCD_SPWG 0x01
1072
1073/* Define display timing
1074*/
1075struct display_timing {
1076 u16 hor_total;
1077 u16 hor_addr;
1078 u16 hor_blank_start;
1079 u16 hor_blank_end;
1080 u16 hor_sync_start;
1081 u16 hor_sync_end;
1082 u16 ver_total;
1083 u16 ver_addr;
1084 u16 ver_blank_start;
1085 u16 ver_blank_end;
1086 u16 ver_sync_start;
1087 u16 ver_sync_end;
1088};
1089
1090struct crt_mode_table {
1091 int refresh_rate;
1092 unsigned long clk;
1093 int h_sync_polarity;
1094 int v_sync_polarity;
1095 struct display_timing crtc;
1096};
1097
1098struct io_reg {
1099 int port;
1100 u8 index;
1101 u8 mask;
1102 u8 value;
1103};
1104
1105#endif /* __SHARE_H__ */
diff --git a/drivers/video/via/tbl1636.c b/drivers/video/via/tbl1636.c
new file mode 100644
index 000000000000..2d8453429d4a
--- /dev/null
+++ b/drivers/video/via/tbl1636.c
@@ -0,0 +1,71 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
14 * for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22#include "global.h"
23struct IODATA COMMON_INIT_TBL_VT1636[] = {
24/* Index, Mask, Value */
25 /* Set panel power sequence timing */
26 {0x10, 0xC0, 0x00},
27 /* T1: VDD on - Data on. Each increment is 1 ms. (50ms = 031h) */
28 {0x0B, 0xFF, 0x40},
29 /* T2: Data on - Backlight on. Each increment is 2 ms. (210ms = 068h) */
30 {0x0C, 0xFF, 0x31},
31 /* T3: Backlight off -Data off. Each increment is 2 ms. (210ms = 068h)*/
32 {0x0D, 0xFF, 0x31},
33 /* T4: Data off - VDD off. Each increment is 1 ms. (50ms = 031h) */
34 {0x0E, 0xFF, 0x68},
35 /* T5: VDD off - VDD on. Each increment is 100 ms. (500ms = 04h) */
36 {0x0F, 0xFF, 0x68},
37 /* LVDS output power up */
38 {0x09, 0xA0, 0xA0},
39 /* turn on back light */
40 {0x10, 0x33, 0x13}
41};
42
43struct IODATA DUAL_CHANNEL_ENABLE_TBL_VT1636[] = {
44/* Index, Mask, Value */
45 {0x08, 0xF0, 0xE0} /* Input Data Mode Select */
46};
47
48struct IODATA SINGLE_CHANNEL_ENABLE_TBL_VT1636[] = {
49/* Index, Mask, Value */
50 {0x08, 0xF0, 0x00} /* Input Data Mode Select */
51};
52
53struct IODATA DITHERING_ENABLE_TBL_VT1636[] = {
54/* Index, Mask, Value */
55 {0x0A, 0x70, 0x50}
56};
57
58struct IODATA DITHERING_DISABLE_TBL_VT1636[] = {
59/* Index, Mask, Value */
60 {0x0A, 0x70, 0x00}
61};
62
63struct IODATA VDD_ON_TBL_VT1636[] = {
64/* Index, Mask, Value */
65 {0x10, 0x20, 0x20}
66};
67
68struct IODATA VDD_OFF_TBL_VT1636[] = {
69/* Index, Mask, Value */
70 {0x10, 0x20, 0x00}
71};
diff --git a/drivers/video/via/tbl1636.h b/drivers/video/via/tbl1636.h
new file mode 100644
index 000000000000..d906055f1511
--- /dev/null
+++ b/drivers/video/via/tbl1636.h
@@ -0,0 +1,34 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
14 * for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22#ifndef _TBL1636_H_
23#define _TBL1636_H_
24#include "hw.h"
25
26extern struct IODATA COMMON_INIT_TBL_VT1636[8];
27extern struct IODATA DUAL_CHANNEL_ENABLE_TBL_VT1636[1];
28extern struct IODATA SINGLE_CHANNEL_ENABLE_TBL_VT1636[1];
29extern struct IODATA DITHERING_ENABLE_TBL_VT1636[1];
30extern struct IODATA DITHERING_DISABLE_TBL_VT1636[1];
31extern struct IODATA VDD_ON_TBL_VT1636[1];
32extern struct IODATA VDD_OFF_TBL_VT1636[1];
33
34#endif /* _VIA_TBL1636_H_ */
diff --git a/drivers/video/via/tblDPASetting.c b/drivers/video/via/tblDPASetting.c
new file mode 100644
index 000000000000..0c4c8cc712f4
--- /dev/null
+++ b/drivers/video/via/tblDPASetting.c
@@ -0,0 +1,109 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
14 * for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22#include "global.h"
23/* For VT3324: */
24struct VT1636_DPA_SETTING VT1636_DPA_SETTING_TBL_VT3324[] = {
25 /* Panel ID, CLK_SEL_ST1[09], CLK_SEL_ST2[08] */
26 {LCD_PANEL_ID0_640X480, 0x00, 0x00}, /* For 640x480 */
27 {LCD_PANEL_ID1_800X600, 0x00, 0x00}, /* For 800x600 */
28 {LCD_PANEL_ID2_1024X768, 0x00, 0x00}, /* For 1024x768 */
29 {LCD_PANEL_ID3_1280X768, 0x00, 0x00}, /* For 1280x768 */
30 {LCD_PANEL_ID4_1280X1024, 0x00, 0x00}, /* For 1280x1024 */
31 {LCD_PANEL_ID5_1400X1050, 0x00, 0x00}, /* For 1400x1050 */
32 {LCD_PANEL_ID6_1600X1200, 0x0B, 0x03} /* For 1600x1200 */
33};
34
35struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3324[] = {
36/* ClkRange, DVP0, DVP0DataDriving, DVP0ClockDriving, DVP1,
37 DVP1Driving, DFPHigh, DFPLow */
38/* CR96, SR2A[5], SR1B[1], SR2A[4], SR1E[2], CR9B,
39 SR65, CR97, CR99 */
40 /* LCK/VCK < 30000000 will use this value */
41 {DPA_CLK_RANGE_30M, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
42 0x00},
43 /* 30000000 < LCK/VCK < 50000000 will use this value */
44 {DPA_CLK_RANGE_30_50M, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
45 0x00},
46 /* 50000000 < LCK/VCK < 70000000 will use this value */
47 {DPA_CLK_RANGE_50_70M, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
48 0x00},
49 /* 70000000 < LCK/VCK < 100000000 will use this value */
50 {DPA_CLK_RANGE_70_100M, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
51 0x00},
52 /* 100000000 < LCK/VCK < 15000000 will use this value */
53 {DPA_CLK_RANGE_100_150M, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
54 0x00},
55 /* 15000000 < LCK/VCK will use this value */
56 {DPA_CLK_RANGE_150M, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0E, 0x00,
57 0x00},
58};
59
60/* For VT3327: */
61struct VT1636_DPA_SETTING VT1636_DPA_SETTING_TBL_VT3327[] = {
62 /* Panel ID, CLK_SEL_ST1[09], CLK_SEL_ST2[08] */
63 {LCD_PANEL_ID0_640X480, 0x00, 0x00}, /* For 640x480 */
64 {LCD_PANEL_ID1_800X600, 0x00, 0x00}, /* For 800x600 */
65 {LCD_PANEL_ID2_1024X768, 0x00, 0x00}, /* For 1024x768 */
66 {LCD_PANEL_ID3_1280X768, 0x00, 0x00}, /* For 1280x768 */
67 {LCD_PANEL_ID4_1280X1024, 0x00, 0x00}, /* For 1280x1024 */
68 {LCD_PANEL_ID5_1400X1050, 0x00, 0x00}, /* For 1400x1050 */
69 {LCD_PANEL_ID6_1600X1200, 0x00, 0x00} /* For 1600x1200 */
70};
71
72struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3327[] = {
73/* ClkRange,DVP0, DVP0DataDriving, DVP0ClockDriving, DVP1,
74 DVP1Driving, DFPHigh, DFPLow */
75/* CR96, SR2A[5], SR1B[1], SR2A[4], SR1E[2], CR9B,
76 SR65, CR97, CR99 */
77/* LCK/VCK < 30000000 will use this value */
78{DPA_CLK_RANGE_30M, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x08, 0x01},
79/* 30000000 < LCK/VCK < 50000000 will use this value */
80{DPA_CLK_RANGE_30_50M, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x08, 0x01},
81/* 50000000 < LCK/VCK < 70000000 will use this value */
82{DPA_CLK_RANGE_50_70M, 0x06, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x08, 0x01},
83/* 70000000 < LCK/VCK < 100000000 will use this value */
84{DPA_CLK_RANGE_70_100M, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x08, 0x03},
85/* 100000000 < LCK/VCK < 15000000 will use this value */
86{DPA_CLK_RANGE_100_150M, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x02},
87/* 15000000 < LCK/VCK will use this value */
88{DPA_CLK_RANGE_150M, 0x00, 0x20, 0x00, 0x10, 0x00, 0x03, 0x00, 0x0D, 0x03},
89};
90
91/* For VT3364: */
92struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3364[] = {
93/* ClkRange,DVP0, DVP0DataDriving, DVP0ClockDriving, DVP1,
94 DVP1Driving, DFPHigh, DFPLow */
95/* CR96, SR2A[5], SR1B[1], SR2A[4], SR1E[2], CR9B,
96 SR65, CR97, CR99 */
97/* LCK/VCK < 30000000 will use this value */
98{DPA_CLK_RANGE_30M, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08},
99/* 30000000 < LCK/VCK < 50000000 will use this value */
100{DPA_CLK_RANGE_30_50M, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08},
101/* 50000000 < LCK/VCK < 70000000 will use this value */
102{DPA_CLK_RANGE_50_70M, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08},
103/* 70000000 < LCK/VCK < 100000000 will use this value */
104{DPA_CLK_RANGE_70_100M, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08},
105/* 100000000 < LCK/VCK < 15000000 will use this value */
106{DPA_CLK_RANGE_100_150M, 0x03, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08},
107/* 15000000 < LCK/VCK will use this value */
108{DPA_CLK_RANGE_150M, 0x01, 0x00, 0x02, 0x10, 0x00, 0x03, 0x00, 0x00, 0x08},
109};
diff --git a/drivers/video/via/tblDPASetting.h b/drivers/video/via/tblDPASetting.h
new file mode 100644
index 000000000000..b065a83481d3
--- /dev/null
+++ b/drivers/video/via/tblDPASetting.h
@@ -0,0 +1,47 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
14 * for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22#ifndef _TBLDPASETTING_H_
23#define _TBLDPASETTING_H_
24#include "global.h"
25
26#define DPA_CLK_30M 30000000
27#define DPA_CLK_50M 50000000
28#define DPA_CLK_70M 70000000
29#define DPA_CLK_100M 100000000
30#define DPA_CLK_150M 150000000
31
32enum DPA_RANGE {
33 DPA_CLK_RANGE_30M,
34 DPA_CLK_RANGE_30_50M,
35 DPA_CLK_RANGE_50_70M,
36 DPA_CLK_RANGE_70_100M,
37 DPA_CLK_RANGE_100_150M,
38 DPA_CLK_RANGE_150M
39};
40
41extern struct VT1636_DPA_SETTING VT1636_DPA_SETTING_TBL_VT3324[7];
42extern struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3324[6];
43extern struct VT1636_DPA_SETTING VT1636_DPA_SETTING_TBL_VT3327[7];
44extern struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3327[];
45extern struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3364[6];
46
47#endif
diff --git a/drivers/video/via/via_i2c.c b/drivers/video/via/via_i2c.c
new file mode 100644
index 000000000000..0f3ed4eb236d
--- /dev/null
+++ b/drivers/video/via/via_i2c.c
@@ -0,0 +1,177 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
14 * for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22#include "global.h"
23
24static void via_i2c_setscl(void *data, int state)
25{
26 u8 val;
27 struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data;
28
29 val = viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0xF0;
30 if (state)
31 val |= 0x20;
32 else
33 val &= ~0x20;
34 switch (via_i2c_chan->i2c_port) {
35 case I2CPORTINDEX:
36 val |= 0x01;
37 break;
38 case GPIOPORTINDEX:
39 val |= 0x80;
40 break;
41 default:
42 DEBUG_MSG("via_i2c: specify wrong i2c port.\n");
43 }
44 viafb_write_reg(via_i2c_chan->i2c_port, VIASR, val);
45}
46
47static int via_i2c_getscl(void *data)
48{
49 struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data;
50
51 if (viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0x08)
52 return 1;
53 return 0;
54}
55
56static int via_i2c_getsda(void *data)
57{
58 struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data;
59
60 if (viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0x04)
61 return 1;
62 return 0;
63}
64
65static void via_i2c_setsda(void *data, int state)
66{
67 u8 val;
68 struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data;
69
70 val = viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0xF0;
71 if (state)
72 val |= 0x10;
73 else
74 val &= ~0x10;
75 switch (via_i2c_chan->i2c_port) {
76 case I2CPORTINDEX:
77 val |= 0x01;
78 break;
79 case GPIOPORTINDEX:
80 val |= 0x40;
81 break;
82 default:
83 DEBUG_MSG("via_i2c: specify wrong i2c port.\n");
84 }
85 viafb_write_reg(via_i2c_chan->i2c_port, VIASR, val);
86}
87
88int viafb_i2c_readbyte(u8 slave_addr, u8 index, u8 *pdata)
89{
90 u8 mm1[] = {0x00};
91 struct i2c_msg msgs[2];
92
93 *pdata = 0;
94 msgs[0].flags = 0;
95 msgs[1].flags = I2C_M_RD;
96 msgs[0].addr = msgs[1].addr = slave_addr / 2;
97 mm1[0] = index;
98 msgs[0].len = 1; msgs[1].len = 1;
99 msgs[0].buf = mm1; msgs[1].buf = pdata;
100 i2c_transfer(&viaparinfo->i2c_stuff.adapter, msgs, 2);
101
102 return 0;
103}
104
105int viafb_i2c_writebyte(u8 slave_addr, u8 index, u8 data)
106{
107 u8 msg[2] = { index, data };
108 struct i2c_msg msgs;
109
110 msgs.flags = 0;
111 msgs.addr = slave_addr / 2;
112 msgs.len = 2;
113 msgs.buf = msg;
114 return i2c_transfer(&viaparinfo->i2c_stuff.adapter, &msgs, 1);
115}
116
117int viafb_i2c_readbytes(u8 slave_addr, u8 index, u8 *buff, int buff_len)
118{
119 u8 mm1[] = {0x00};
120 struct i2c_msg msgs[2];
121
122 msgs[0].flags = 0;
123 msgs[1].flags = I2C_M_RD;
124 msgs[0].addr = msgs[1].addr = slave_addr / 2;
125 mm1[0] = index;
126 msgs[0].len = 1; msgs[1].len = buff_len;
127 msgs[0].buf = mm1; msgs[1].buf = buff;
128 i2c_transfer(&viaparinfo->i2c_stuff.adapter, msgs, 2);
129 return 0;
130}
131
132int viafb_create_i2c_bus(void *viapar)
133{
134 int ret;
135 struct viafb_par *par = (struct viafb_par *)viapar;
136
137 strcpy(par->i2c_stuff.adapter.name, "via_i2c");
138 par->i2c_stuff.i2c_port = 0x0;
139 par->i2c_stuff.adapter.owner = THIS_MODULE;
140 par->i2c_stuff.adapter.id = 0x01FFFF;
141 par->i2c_stuff.adapter.class = 0;
142 par->i2c_stuff.adapter.algo_data = &par->i2c_stuff.algo;
143 par->i2c_stuff.adapter.dev.parent = NULL;
144 par->i2c_stuff.algo.setsda = via_i2c_setsda;
145 par->i2c_stuff.algo.setscl = via_i2c_setscl;
146 par->i2c_stuff.algo.getsda = via_i2c_getsda;
147 par->i2c_stuff.algo.getscl = via_i2c_getscl;
148 par->i2c_stuff.algo.udelay = 40;
149 par->i2c_stuff.algo.timeout = 20;
150 par->i2c_stuff.algo.data = &par->i2c_stuff;
151
152 i2c_set_adapdata(&par->i2c_stuff.adapter, &par->i2c_stuff);
153
154 /* Raise SCL and SDA */
155 par->i2c_stuff.i2c_port = I2CPORTINDEX;
156 via_i2c_setsda(&par->i2c_stuff, 1);
157 via_i2c_setscl(&par->i2c_stuff, 1);
158
159 par->i2c_stuff.i2c_port = GPIOPORTINDEX;
160 via_i2c_setsda(&par->i2c_stuff, 1);
161 via_i2c_setscl(&par->i2c_stuff, 1);
162 udelay(20);
163
164 ret = i2c_bit_add_bus(&par->i2c_stuff.adapter);
165 if (ret == 0)
166 DEBUG_MSG("I2C bus %s registered.\n",
167 par->i2c_stuff.adapter.name);
168 else
169 DEBUG_MSG("Failed to register I2C bus %s.\n",
170 par->i2c_stuff.adapter.name);
171 return ret;
172}
173
174void viafb_delete_i2c_buss(void *par)
175{
176 i2c_del_adapter(&((struct viafb_par *)par)->i2c_stuff.adapter);
177}
diff --git a/drivers/video/via/via_i2c.h b/drivers/video/via/via_i2c.h
new file mode 100644
index 000000000000..3a13242a3152
--- /dev/null
+++ b/drivers/video/via/via_i2c.h
@@ -0,0 +1,46 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
14 * for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21#ifndef __VIA_I2C_H__
22#define __VIA_I2C_H__
23
24#include <linux/i2c.h>
25#include <linux/i2c-algo-bit.h>
26
27struct via_i2c_stuff {
28 u16 i2c_port; /* GPIO or I2C port */
29 struct i2c_adapter adapter;
30 struct i2c_algo_bit_data algo;
31};
32
33#define I2CPORT 0x3c4
34#define I2CPORTINDEX 0x31
35#define GPIOPORT 0x3C4
36#define GPIOPORTINDEX 0x2C
37#define I2C_BUS 1
38#define GPIO_BUS 2
39#define DELAYPORT 0x3C3
40
41int viafb_i2c_readbyte(u8 slave_addr, u8 index, u8 *pdata);
42int viafb_i2c_writebyte(u8 slave_addr, u8 index, u8 data);
43int viafb_i2c_readbytes(u8 slave_addr, u8 index, u8 *buff, int buff_len);
44int viafb_create_i2c_bus(void *par);
45void viafb_delete_i2c_buss(void *par);
46#endif /* __VIA_I2C_H__ */
diff --git a/drivers/video/via/via_utility.c b/drivers/video/via/via_utility.c
new file mode 100644
index 000000000000..d53c3d54ed8e
--- /dev/null
+++ b/drivers/video/via/via_utility.c
@@ -0,0 +1,253 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
14 * for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22#include "global.h"
23
24void viafb_get_device_support_state(u32 *support_state)
25{
26 *support_state = CRT_Device;
27
28 if (viaparinfo->chip_info->tmds_chip_info.tmds_chip_name == VT1632_TMDS)
29 *support_state |= DVI_Device;
30
31 if (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name == VT1631_LVDS)
32 *support_state |= LCD_Device;
33}
34
35void viafb_get_device_connect_state(u32 *connect_state)
36{
37 bool mobile = false;
38
39 *connect_state = CRT_Device;
40
41 if (viafb_dvi_sense())
42 *connect_state |= DVI_Device;
43
44 viafb_lcd_get_mobile_state(&mobile);
45 if (mobile)
46 *connect_state |= LCD_Device;
47}
48
49bool viafb_lcd_get_support_expand_state(u32 xres, u32 yres)
50{
51 unsigned int support_state = 0;
52
53 switch (viafb_lcd_panel_id) {
54 case LCD_PANEL_ID0_640X480:
55 if ((xres < 640) && (yres < 480))
56 support_state = true;
57 break;
58
59 case LCD_PANEL_ID1_800X600:
60 if ((xres < 800) && (yres < 600))
61 support_state = true;
62 break;
63
64 case LCD_PANEL_ID2_1024X768:
65 if ((xres < 1024) && (yres < 768))
66 support_state = true;
67 break;
68
69 case LCD_PANEL_ID3_1280X768:
70 if ((xres < 1280) && (yres < 768))
71 support_state = true;
72 break;
73
74 case LCD_PANEL_ID4_1280X1024:
75 if ((xres < 1280) && (yres < 1024))
76 support_state = true;
77 break;
78
79 case LCD_PANEL_ID5_1400X1050:
80 if ((xres < 1400) && (yres < 1050))
81 support_state = true;
82 break;
83
84 case LCD_PANEL_ID6_1600X1200:
85 if ((xres < 1600) && (yres < 1200))
86 support_state = true;
87 break;
88
89 case LCD_PANEL_ID7_1366X768:
90 if ((xres < 1366) && (yres < 768))
91 support_state = true;
92 break;
93
94 case LCD_PANEL_ID8_1024X600:
95 if ((xres < 1024) && (yres < 600))
96 support_state = true;
97 break;
98
99 case LCD_PANEL_ID9_1280X800:
100 if ((xres < 1280) && (yres < 800))
101 support_state = true;
102 break;
103
104 case LCD_PANEL_IDA_800X480:
105 if ((xres < 800) && (yres < 480))
106 support_state = true;
107 break;
108
109 case LCD_PANEL_IDB_1360X768:
110 if ((xres < 1360) && (yres < 768))
111 support_state = true;
112 break;
113
114 case LCD_PANEL_IDC_480X640:
115 if ((xres < 480) && (yres < 640))
116 support_state = true;
117 break;
118
119 default:
120 support_state = false;
121 break;
122 }
123
124 return support_state;
125}
126
127/*====================================================================*/
128/* Gamma Function Implementation*/
129/*====================================================================*/
130
131void viafb_set_gamma_table(int bpp, unsigned int *gamma_table)
132{
133 int i, sr1a;
134 int active_device_amount = 0;
135 int device_status = viafb_DeviceStatus;
136
137 for (i = 0; i < sizeof(viafb_DeviceStatus) * 8; i++) {
138 if (device_status & 1)
139 active_device_amount++;
140 device_status >>= 1;
141 }
142
143 /* 8 bpp mode can't adjust gamma */
144 if (bpp == 8)
145 return ;
146
147 /* Enable Gamma */
148 switch (viaparinfo->chip_info->gfx_chip_name) {
149 case UNICHROME_CLE266:
150 case UNICHROME_K400:
151 viafb_write_reg_mask(SR16, VIASR, 0x80, BIT7);
152 break;
153
154 case UNICHROME_K800:
155 case UNICHROME_PM800:
156 case UNICHROME_CN700:
157 case UNICHROME_CX700:
158 case UNICHROME_K8M890:
159 case UNICHROME_P4M890:
160 case UNICHROME_P4M900:
161 viafb_write_reg_mask(CR33, VIACR, 0x80, BIT7);
162 break;
163 }
164 sr1a = (unsigned int)viafb_read_reg(VIASR, SR1A);
165 viafb_write_reg_mask(SR1A, VIASR, 0x0, BIT0);
166
167 /* Fill IGA1 Gamma Table */
168 outb(0, LUT_INDEX_WRITE);
169 for (i = 0; i < 256; i++) {
170 outb(gamma_table[i] >> 16, LUT_DATA);
171 outb(gamma_table[i] >> 8 & 0xFF, LUT_DATA);
172 outb(gamma_table[i] & 0xFF, LUT_DATA);
173 }
174
175 /* If adjust Gamma value in SAMM, fill IGA1,
176 IGA2 Gamma table simultanous. */
177 /* Switch to IGA2 Gamma Table */
178 if ((active_device_amount > 1) &&
179 !((viaparinfo->chip_info->gfx_chip_name ==
180 UNICHROME_CLE266) &&
181 (viaparinfo->chip_info->gfx_chip_revision < 15))) {
182 viafb_write_reg_mask(SR1A, VIASR, 0x01, BIT0);
183 viafb_write_reg_mask(CR6A, VIACR, 0x02, BIT1);
184
185 /* Fill IGA2 Gamma Table */
186 outb(0, LUT_INDEX_WRITE);
187 for (i = 0; i < 256; i++) {
188 outb(gamma_table[i] >> 16, LUT_DATA);
189 outb(gamma_table[i] >> 8 & 0xFF, LUT_DATA);
190 outb(gamma_table[i] & 0xFF, LUT_DATA);
191 }
192 }
193 viafb_write_reg(SR1A, VIASR, sr1a);
194}
195
196void viafb_get_gamma_table(unsigned int *gamma_table)
197{
198 unsigned char color_r, color_g, color_b;
199 unsigned char sr1a = 0;
200 int i;
201
202 /* Enable Gamma */
203 switch (viaparinfo->chip_info->gfx_chip_name) {
204 case UNICHROME_CLE266:
205 case UNICHROME_K400:
206 viafb_write_reg_mask(SR16, VIASR, 0x80, BIT7);
207 break;
208
209 case UNICHROME_K800:
210 case UNICHROME_PM800:
211 case UNICHROME_CN700:
212 case UNICHROME_CX700:
213 case UNICHROME_K8M890:
214 case UNICHROME_P4M890:
215 case UNICHROME_P4M900:
216 viafb_write_reg_mask(CR33, VIACR, 0x80, BIT7);
217 break;
218 }
219 sr1a = viafb_read_reg(VIASR, SR1A);
220 viafb_write_reg_mask(SR1A, VIASR, 0x0, BIT0);
221
222 /* Reading gamma table to get color value */
223 outb(0, LUT_INDEX_READ);
224 for (i = 0; i < 256; i++) {
225 color_r = inb(LUT_DATA);
226 color_g = inb(LUT_DATA);
227 color_b = inb(LUT_DATA);
228 gamma_table[i] =
229 ((((u32) color_r) << 16) |
230 (((u16) color_g) << 8)) | color_b;
231 }
232 viafb_write_reg(SR1A, VIASR, sr1a);
233}
234
235void viafb_get_gamma_support_state(int bpp, unsigned int *support_state)
236{
237 if (bpp == 8)
238 *support_state = None_Device;
239 else
240 *support_state = CRT_Device | DVI_Device | LCD_Device;
241}
242
243int viafb_input_parameter_converter(int parameter_value)
244{
245 int result;
246
247 if (parameter_value >= 1 && parameter_value <= 9)
248 result = 1 << (parameter_value - 1);
249 else
250 result = 1;
251
252 return result;
253}
diff --git a/drivers/video/via/via_utility.h b/drivers/video/via/via_utility.h
new file mode 100644
index 000000000000..2fd455202ebd
--- /dev/null
+++ b/drivers/video/via/via_utility.h
@@ -0,0 +1,35 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
14 * for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21#ifndef __VIAUTILITY_H__
22#define __VIAUTILITY_H__
23
24/* These functions are used to get infomation about device's state */
25void viafb_get_device_support_state(u32 *support_state);
26void viafb_get_device_connect_state(u32 *connect_state);
27bool viafb_lcd_get_support_expand_state(u32 xres, u32 yres);
28
29/* These function are used to access gamma table */
30void viafb_set_gamma_table(int bpp, unsigned int *gamma_table);
31void viafb_get_gamma_table(unsigned int *gamma_table);
32void viafb_get_gamma_support_state(int bpp, unsigned int *support_state);
33int viafb_input_parameter_converter(int parameter_value);
34
35#endif /* __VIAUTILITY_H__ */
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c
new file mode 100644
index 000000000000..0132eae06f55
--- /dev/null
+++ b/drivers/video/via/viafbdev.c
@@ -0,0 +1,2571 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
14 * for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22#include <linux/module.h>
23#define _MASTER_FILE
24
25#include "global.h"
26
27static int MAX_CURS = 32;
28static struct fb_var_screeninfo default_var;
29static char *viafb_name = "Via";
30static u32 pseudo_pal[17];
31
32/* video mode */
33static char *viafb_mode = "640x480";
34static char *viafb_mode1 = "640x480";
35static int viafb_resMode = VIA_RES_640X480;
36
37/* Added for specifying active devices.*/
38char *viafb_active_dev = "";
39
40/* Added for specifying video on devices.*/
41char *viafb_video_dev = "";
42
43/*Added for specify lcd output port*/
44char *viafb_lcd_port = "";
45char *viafb_dvi_port = "";
46
47static void viafb_set_device(struct device_t active_dev);
48static int apply_device_setting(struct viafb_ioctl_setting setting_info,
49 struct fb_info *info);
50static void apply_second_mode_setting(struct fb_var_screeninfo
51 *sec_var);
52static void retrieve_device_setting(struct viafb_ioctl_setting
53 *setting_info);
54static void viafb_set_video_device(u32 video_dev_info);
55static void viafb_get_video_device(u32 *video_dev_info);
56
57/* Mode information */
58static const struct viafb_modeinfo viafb_modentry[] = {
59 {480, 640, VIA_RES_480X640, "480x640"},
60 {640, 480, VIA_RES_640X480, "640x480"},
61 {800, 480, VIA_RES_800X480, "800x480"},
62 {800, 600, VIA_RES_800X600, "800x600"},
63 {1024, 768, VIA_RES_1024X768, "1024x768"},
64 {1152, 864, VIA_RES_1152X864, "1152x864"},
65 {1280, 1024, VIA_RES_1280X1024, "1280x1024"},
66 {1600, 1200, VIA_RES_1600X1200, "1600x1200"},
67 {1440, 1050, VIA_RES_1440X1050, "1440x1050"},
68 {1280, 768, VIA_RES_1280X768, "1280x768"},
69 {1280, 800, VIA_RES_1280X800, "1280x800"},
70 {1280, 960, VIA_RES_1280X960, "1280x960"},
71 {1920, 1440, VIA_RES_1920X1440, "1920x1440"},
72 {848, 480, VIA_RES_848X480, "848x480"},
73 {1400, 1050, VIA_RES_1400X1050, "1400x1050"},
74 {720, 480, VIA_RES_720X480, "720x480"},
75 {720, 576, VIA_RES_720X576, "720x576"},
76 {1024, 512, VIA_RES_1024X512, "1024x512"},
77 {1024, 576, VIA_RES_1024X576, "1024x576"},
78 {1024, 600, VIA_RES_1024X600, "1024x600"},
79 {1280, 720, VIA_RES_1280X720, "1280x720"},
80 {1920, 1080, VIA_RES_1920X1080, "1920x1080"},
81 {1366, 768, VIA_RES_1368X768, "1368x768"},
82 {1680, 1050, VIA_RES_1680X1050, "1680x1050"},
83 {960, 600, VIA_RES_960X600, "960x600"},
84 {1000, 600, VIA_RES_1000X600, "1000x600"},
85 {1024, 576, VIA_RES_1024X576, "1024x576"},
86 {1024, 600, VIA_RES_1024X600, "1024x600"},
87 {1088, 612, VIA_RES_1088X612, "1088x612"},
88 {1152, 720, VIA_RES_1152X720, "1152x720"},
89 {1200, 720, VIA_RES_1200X720, "1200x720"},
90 {1280, 600, VIA_RES_1280X600, "1280x600"},
91 {1360, 768, VIA_RES_1360X768, "1360x768"},
92 {1440, 900, VIA_RES_1440X900, "1440x900"},
93 {1600, 900, VIA_RES_1600X900, "1600x900"},
94 {1600, 1024, VIA_RES_1600X1024, "1600x1024"},
95 {1792, 1344, VIA_RES_1792X1344, "1792x1344"},
96 {1856, 1392, VIA_RES_1856X1392, "1856x1392"},
97 {1920, 1200, VIA_RES_1920X1200, "1920x1200"},
98 {2048, 1536, VIA_RES_2048X1536, "2048x1536"},
99 {0, 0, VIA_RES_INVALID, "640x480"}
100};
101
102static struct fb_ops viafb_ops;
103
104static int viafb_update_fix(struct fb_fix_screeninfo *fix, struct fb_info *info)
105{
106 struct viafb_par *ppar;
107 ppar = info->par;
108
109 DEBUG_MSG(KERN_INFO "viafb_update_fix!\n");
110
111 fix->visual =
112 ppar->bpp == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
113 fix->line_length = ppar->linelength;
114
115 return 0;
116}
117
118
119static void viafb_setup_fixinfo(struct fb_fix_screeninfo *fix,
120 struct viafb_par *viaparinfo)
121{
122 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
123 strcpy(fix->id, viafb_name);
124
125 fix->smem_start = viaparinfo->fbmem;
126 fix->smem_len = viaparinfo->fbmem_free;
127 fix->mmio_start = viaparinfo->mmio_base;
128 fix->mmio_len = viaparinfo->mmio_len;
129
130 fix->type = FB_TYPE_PACKED_PIXELS;
131 fix->type_aux = 0;
132
133 fix->xpanstep = fix->ywrapstep = 0;
134 fix->ypanstep = 1;
135
136 /* Just tell the accel name */
137 viafbinfo->fix.accel = FB_ACCEL_VIA_UNICHROME;
138}
139static int viafb_open(struct fb_info *info, int user)
140{
141 DEBUG_MSG(KERN_INFO "viafb_open!\n");
142 return 0;
143}
144
145static int viafb_release(struct fb_info *info, int user)
146{
147 DEBUG_MSG(KERN_INFO "viafb_release!\n");
148 return 0;
149}
150
151static void viafb_update_viafb_par(struct fb_info *info)
152{
153 struct viafb_par *ppar;
154
155 ppar = info->par;
156 ppar->bpp = info->var.bits_per_pixel;
157 ppar->linelength = ((info->var.xres_virtual + 7) & ~7) * ppar->bpp / 8;
158 ppar->hres = info->var.xres;
159 ppar->vres = info->var.yres;
160 ppar->xoffset = info->var.xoffset;
161 ppar->yoffset = info->var.yoffset;
162}
163
164static int viafb_check_var(struct fb_var_screeninfo *var,
165 struct fb_info *info)
166{
167 int vmode_index, htotal, vtotal;
168 struct viafb_par *ppar;
169 u32 long_refresh;
170 struct viafb_par *p_viafb_par;
171 ppar = info->par;
172
173
174 DEBUG_MSG(KERN_INFO "viafb_check_var!\n");
175 /* Sanity check */
176 /* HW neither support interlacte nor double-scaned mode */
177 if (var->vmode & FB_VMODE_INTERLACED || var->vmode & FB_VMODE_DOUBLE)
178 return -EINVAL;
179
180 vmode_index = viafb_get_mode_index(var->xres, var->yres, 0);
181 if (vmode_index == VIA_RES_INVALID) {
182 DEBUG_MSG(KERN_INFO
183 "viafb: Mode %dx%dx%d not supported!!\n",
184 var->xres, var->yres, var->bits_per_pixel);
185 return -EINVAL;
186 }
187
188 if (24 == var->bits_per_pixel)
189 var->bits_per_pixel = 32;
190
191 if (var->bits_per_pixel != 8 && var->bits_per_pixel != 16 &&
192 var->bits_per_pixel != 32)
193 return -EINVAL;
194
195 if ((var->xres_virtual * (var->bits_per_pixel >> 3)) & 0x1F)
196 /*32 pixel alignment */
197 var->xres_virtual = (var->xres_virtual + 31) & ~31;
198 if (var->xres_virtual * var->yres_virtual * var->bits_per_pixel / 8 >
199 ppar->memsize)
200 return -EINVAL;
201
202 /* Based on var passed in to calculate the refresh,
203 * because our driver use some modes special.
204 */
205 htotal = var->xres + var->left_margin +
206 var->right_margin + var->hsync_len;
207 vtotal = var->yres + var->upper_margin +
208 var->lower_margin + var->vsync_len;
209 long_refresh = 1000000000UL / var->pixclock * 1000;
210 long_refresh /= (htotal * vtotal);
211
212 viafb_refresh = viafb_get_refresh(var->xres, var->yres, long_refresh);
213
214 /* Adjust var according to our driver's own table */
215 viafb_fill_var_timing_info(var, viafb_refresh, vmode_index);
216
217 /* This is indeed a patch for VT3353 */
218 if (!info->par)
219 return -1;
220 p_viafb_par = (struct viafb_par *)info->par;
221 if (p_viafb_par->chip_info->gfx_chip_name == UNICHROME_VX800)
222 var->accel_flags = 0;
223
224 return 0;
225}
226
227static int viafb_set_par(struct fb_info *info)
228{
229 int vmode_index;
230 int vmode_index1 = 0;
231 DEBUG_MSG(KERN_INFO "viafb_set_par!\n");
232
233 viafb_update_device_setting(info->var.xres, info->var.yres,
234 info->var.bits_per_pixel, viafb_refresh, 0);
235
236 vmode_index = viafb_get_mode_index(info->var.xres, info->var.yres, 0);
237
238 if (viafb_SAMM_ON == 1) {
239 DEBUG_MSG(KERN_INFO
240 "viafb_second_xres = %d, viafb_second_yres = %d, bpp = %d\n",
241 viafb_second_xres, viafb_second_yres, viafb_bpp1);
242 vmode_index1 = viafb_get_mode_index(viafb_second_xres,
243 viafb_second_yres, 1);
244 DEBUG_MSG(KERN_INFO "->viafb_SAMM_ON: index=%d\n",
245 vmode_index1);
246
247 viafb_update_device_setting(viafb_second_xres,
248 viafb_second_yres, viafb_bpp1, viafb_refresh1, 1);
249 }
250
251 if (vmode_index != VIA_RES_INVALID) {
252 viafb_setmode(vmode_index, info->var.xres, info->var.yres,
253 info->var.bits_per_pixel, vmode_index1,
254 viafb_second_xres, viafb_second_yres, viafb_bpp1);
255
256 /*We should set memory offset according virtual_x */
257 /*Fix me:put this function into viafb_setmode */
258 viafb_memory_pitch_patch(info);
259
260 /* Update ***fb_par information */
261 viafb_update_viafb_par(info);
262
263 /* Update other fixed information */
264 viafb_update_fix(&info->fix, info);
265 viafb_bpp = info->var.bits_per_pixel;
266 /* Update viafb_accel, it is necessary to our 2D accelerate */
267 viafb_accel = info->var.accel_flags;
268
269 if (viafb_accel)
270 viafb_set_2d_color_depth(info->var.bits_per_pixel);
271 }
272
273 return 0;
274}
275
276/* Set one color register */
277static int viafb_setcolreg(unsigned regno, unsigned red, unsigned green,
278unsigned blue, unsigned transp, struct fb_info *info)
279{
280 u8 sr1a, sr1b, cr67, cr6a, rev = 0, shift = 10;
281 unsigned cmap_entries = (info->var.bits_per_pixel == 8) ? 256 : 16;
282 DEBUG_MSG(KERN_INFO "viafb_setcolreg!\n");
283 if (regno >= cmap_entries)
284 return 1;
285 if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name) {
286 /*
287 * Read PCI bus 0,dev 0,function 0,index 0xF6 to get chip rev.
288 */
289 outl(0x80000000 | (0xf6 & ~3), (unsigned long)0xCF8);
290 rev = (inl((unsigned long)0xCFC) >> ((0xf6 & 3) * 8)) & 0xff;
291 }
292 switch (info->var.bits_per_pixel) {
293 case 8:
294 outb(0x1A, 0x3C4);
295 sr1a = inb(0x3C5);
296 outb(0x1B, 0x3C4);
297 sr1b = inb(0x3C5);
298 outb(0x67, 0x3D4);
299 cr67 = inb(0x3D5);
300 outb(0x6A, 0x3D4);
301 cr6a = inb(0x3D5);
302
303 /* Map the 3C6/7/8/9 to the IGA2 */
304 outb(0x1A, 0x3C4);
305 outb(sr1a | 0x01, 0x3C5);
306 /* Second Display Engine colck always on */
307 outb(0x1B, 0x3C4);
308 outb(sr1b | 0x80, 0x3C5);
309 /* Second Display Color Depth 8 */
310 outb(0x67, 0x3D4);
311 outb(cr67 & 0x3F, 0x3D5);
312 outb(0x6A, 0x3D4);
313 /* Second Display Channel Reset CR6A[6]) */
314 outb(cr6a & 0xBF, 0x3D5);
315 /* Second Display Channel Enable CR6A[7] */
316 outb(cr6a | 0x80, 0x3D5);
317 /* Second Display Channel stop reset) */
318 outb(cr6a | 0x40, 0x3D5);
319
320 /* Bit mask of palette */
321 outb(0xFF, 0x3c6);
322 /* Write one register of IGA2 */
323 outb(regno, 0x3C8);
324 if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name &&
325 rev >= 15) {
326 shift = 8;
327 viafb_write_reg_mask(CR6A, VIACR, BIT5, BIT5);
328 viafb_write_reg_mask(SR15, VIASR, BIT7, BIT7);
329 } else {
330 shift = 10;
331 viafb_write_reg_mask(CR6A, VIACR, 0, BIT5);
332 viafb_write_reg_mask(SR15, VIASR, 0, BIT7);
333 }
334 outb(red >> shift, 0x3C9);
335 outb(green >> shift, 0x3C9);
336 outb(blue >> shift, 0x3C9);
337
338 /* Map the 3C6/7/8/9 to the IGA1 */
339 outb(0x1A, 0x3C4);
340 outb(sr1a & 0xFE, 0x3C5);
341 /* Bit mask of palette */
342 outb(0xFF, 0x3c6);
343 /* Write one register of IGA1 */
344 outb(regno, 0x3C8);
345 outb(red >> shift, 0x3C9);
346 outb(green >> shift, 0x3C9);
347 outb(blue >> shift, 0x3C9);
348
349 outb(0x1A, 0x3C4);
350 outb(sr1a, 0x3C5);
351 outb(0x1B, 0x3C4);
352 outb(sr1b, 0x3C5);
353 outb(0x67, 0x3D4);
354 outb(cr67, 0x3D5);
355 outb(0x6A, 0x3D4);
356 outb(cr6a, 0x3D5);
357 break;
358 case 16:
359 ((u32 *) info->pseudo_palette)[regno] = (red & 0xF800) |
360 ((green & 0xFC00) >> 5) | ((blue & 0xF800) >> 11);
361 break;
362 case 32:
363 ((u32 *) info->pseudo_palette)[regno] =
364 ((transp & 0xFF00) << 16) |
365 ((red & 0xFF00) << 8) |
366 ((green & 0xFF00)) | ((blue & 0xFF00) >> 8);
367 break;
368 }
369
370 return 0;
371
372}
373
374/*CALLED BY: fb_set_cmap */
375/* fb_set_var, pass 256 colors */
376/*CALLED BY: fb_set_cmap */
377/* fbcon_set_palette, pass 16 colors */
378static int viafb_setcmap(struct fb_cmap *cmap, struct fb_info *info)
379{
380 u32 len = cmap->len;
381 u32 i;
382 u16 *pred = cmap->red;
383 u16 *pgreen = cmap->green;
384 u16 *pblue = cmap->blue;
385 u16 *ptransp = cmap->transp;
386 u8 sr1a, sr1b, cr67, cr6a, rev = 0, shift = 10;
387 if (len > 256)
388 return 1;
389 if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name) {
390 /*
391 * Read PCI bus 0, dev 0, function 0, index 0xF6 to get chip
392 * rev.
393 */
394 outl(0x80000000 | (0xf6 & ~3), (unsigned long)0xCF8);
395 rev = (inl((unsigned long)0xCFC) >> ((0xf6 & 3) * 8)) & 0xff;
396 }
397 switch (info->var.bits_per_pixel) {
398 case 8:
399 outb(0x1A, 0x3C4);
400 sr1a = inb(0x3C5);
401 outb(0x1B, 0x3C4);
402 sr1b = inb(0x3C5);
403 outb(0x67, 0x3D4);
404 cr67 = inb(0x3D5);
405 outb(0x6A, 0x3D4);
406 cr6a = inb(0x3D5);
407 /* Map the 3C6/7/8/9 to the IGA2 */
408 outb(0x1A, 0x3C4);
409 outb(sr1a | 0x01, 0x3C5);
410 outb(0x1B, 0x3C4);
411 /* Second Display Engine colck always on */
412 outb(sr1b | 0x80, 0x3C5);
413 outb(0x67, 0x3D4);
414 /* Second Display Color Depth 8 */
415 outb(cr67 & 0x3F, 0x3D5);
416 outb(0x6A, 0x3D4);
417 /* Second Display Channel Reset CR6A[6]) */
418 outb(cr6a & 0xBF, 0x3D5);
419 /* Second Display Channel Enable CR6A[7] */
420 outb(cr6a | 0x80, 0x3D5);
421 /* Second Display Channel stop reset) */
422 outb(cr6a | 0xC0, 0x3D5);
423
424 /* Bit mask of palette */
425 outb(0xFF, 0x3c6);
426 outb(0x00, 0x3C8);
427 if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name &&
428 rev >= 15) {
429 shift = 8;
430 viafb_write_reg_mask(CR6A, VIACR, BIT5, BIT5);
431 viafb_write_reg_mask(SR15, VIASR, BIT7, BIT7);
432 } else {
433 shift = 10;
434 viafb_write_reg_mask(CR6A, VIACR, 0, BIT5);
435 viafb_write_reg_mask(SR15, VIASR, 0, BIT7);
436 }
437 for (i = 0; i < len; i++) {
438 outb((*(pred + i)) >> shift, 0x3C9);
439 outb((*(pgreen + i)) >> shift, 0x3C9);
440 outb((*(pblue + i)) >> shift, 0x3C9);
441 }
442
443 outb(0x1A, 0x3C4);
444 /* Map the 3C6/7/8/9 to the IGA1 */
445 outb(sr1a & 0xFE, 0x3C5);
446 /* Bit mask of palette */
447 outb(0xFF, 0x3c6);
448 outb(0x00, 0x3C8);
449 for (i = 0; i < len; i++) {
450 outb((*(pred + i)) >> shift, 0x3C9);
451 outb((*(pgreen + i)) >> shift, 0x3C9);
452 outb((*(pblue + i)) >> shift, 0x3C9);
453 }
454
455 outb(0x1A, 0x3C4);
456 outb(sr1a, 0x3C5);
457 outb(0x1B, 0x3C4);
458 outb(sr1b, 0x3C5);
459 outb(0x67, 0x3D4);
460 outb(cr67, 0x3D5);
461 outb(0x6A, 0x3D4);
462 outb(cr6a, 0x3D5);
463 break;
464 case 16:
465 if (len > 17)
466 return 0; /* Because static u32 pseudo_pal[17]; */
467 for (i = 0; i < len; i++)
468 ((u32 *) info->pseudo_palette)[i] =
469 (*(pred + i) & 0xF800) |
470 ((*(pgreen + i) & 0xFC00) >> 5) |
471 ((*(pblue + i) & 0xF800) >> 11);
472 break;
473 case 32:
474 if (len > 17)
475 return 0;
476 if (ptransp) {
477 for (i = 0; i < len; i++)
478 ((u32 *) info->pseudo_palette)[i] =
479 ((*(ptransp + i) & 0xFF00) << 16) |
480 ((*(pred + i) & 0xFF00) << 8) |
481 ((*(pgreen + i) & 0xFF00)) |
482 ((*(pblue + i) & 0xFF00) >> 8);
483 } else {
484 for (i = 0; i < len; i++)
485 ((u32 *) info->pseudo_palette)[i] =
486 0x00000000 |
487 ((*(pred + i) & 0xFF00) << 8) |
488 ((*(pgreen + i) & 0xFF00)) |
489 ((*(pblue + i) & 0xFF00) >> 8);
490 }
491 break;
492 }
493 return 0;
494}
495
496static int viafb_pan_display(struct fb_var_screeninfo *var,
497 struct fb_info *info)
498{
499 unsigned int offset;
500
501 DEBUG_MSG(KERN_INFO "viafb_pan_display!\n");
502
503 offset = (var->xoffset + (var->yoffset * var->xres_virtual)) *
504 var->bits_per_pixel / 16;
505
506 DEBUG_MSG(KERN_INFO "\nviafb_pan_display,offset =%d ", offset);
507
508 viafb_write_reg_mask(0x48, 0x3d4, ((offset >> 24) & 0x3), 0x3);
509 viafb_write_reg_mask(0x34, 0x3d4, ((offset >> 16) & 0xff), 0xff);
510 viafb_write_reg_mask(0x0c, 0x3d4, ((offset >> 8) & 0xff), 0xff);
511 viafb_write_reg_mask(0x0d, 0x3d4, (offset & 0xff), 0xff);
512
513 return 0;
514}
515
516static int viafb_blank(int blank_mode, struct fb_info *info)
517{
518 DEBUG_MSG(KERN_INFO "viafb_blank!\n");
519 /* clear DPMS setting */
520
521 switch (blank_mode) {
522 case FB_BLANK_UNBLANK:
523 /* Screen: On, HSync: On, VSync: On */
524 /* control CRT monitor power management */
525 viafb_write_reg_mask(CR36, VIACR, 0x00, BIT4 + BIT5);
526 break;
527 case FB_BLANK_HSYNC_SUSPEND:
528 /* Screen: Off, HSync: Off, VSync: On */
529 /* control CRT monitor power management */
530 viafb_write_reg_mask(CR36, VIACR, 0x10, BIT4 + BIT5);
531 break;
532 case FB_BLANK_VSYNC_SUSPEND:
533 /* Screen: Off, HSync: On, VSync: Off */
534 /* control CRT monitor power management */
535 viafb_write_reg_mask(CR36, VIACR, 0x20, BIT4 + BIT5);
536 break;
537 case FB_BLANK_POWERDOWN:
538 /* Screen: Off, HSync: Off, VSync: Off */
539 /* control CRT monitor power management */
540 viafb_write_reg_mask(CR36, VIACR, 0x30, BIT4 + BIT5);
541 break;
542 }
543
544 return 0;
545}
546
547static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
548{
549 struct viafb_ioctl_mode viamode;
550 struct viafb_ioctl_samm viasamm;
551 struct viafb_driver_version driver_version;
552 struct fb_var_screeninfo sec_var;
553 struct _panel_size_pos_info panel_pos_size_para;
554 u32 state_info = 0;
555 u32 viainfo_size = sizeof(struct viafb_ioctl_info);
556 u32 *viafb_gamma_table;
557 char driver_name[] = "viafb";
558
559 u32 __user *argp = (u32 __user *) arg;
560 u32 gpu32;
561 u32 video_dev_info = 0;
562 struct viafb_ioctl_setting viafb_setting = {};
563 struct device_t active_dev = {};
564
565 DEBUG_MSG(KERN_INFO "viafb_ioctl: 0x%X !!\n", cmd);
566
567 switch (cmd) {
568 case VIAFB_GET_CHIP_INFO:
569 if (copy_to_user(argp, viaparinfo->chip_info,
570 sizeof(struct chip_information)))
571 return -EFAULT;
572 break;
573 case VIAFB_GET_INFO_SIZE:
574 return put_user(viainfo_size, argp);
575 case VIAFB_GET_INFO:
576 return viafb_ioctl_get_viafb_info(arg);
577 case VIAFB_HOTPLUG:
578 return put_user(viafb_ioctl_hotplug(info->var.xres,
579 info->var.yres,
580 info->var.bits_per_pixel), argp);
581 case VIAFB_SET_HOTPLUG_FLAG:
582 if (copy_from_user(&gpu32, argp, sizeof(gpu32)))
583 return -EFAULT;
584 viafb_hotplug = (gpu32) ? 1 : 0;
585 break;
586 case VIAFB_GET_RESOLUTION:
587 viamode.xres = (u32) viafb_hotplug_Xres;
588 viamode.yres = (u32) viafb_hotplug_Yres;
589 viamode.refresh = (u32) viafb_hotplug_refresh;
590 viamode.bpp = (u32) viafb_hotplug_bpp;
591 if (viafb_SAMM_ON == 1) {
592 viamode.xres_sec = viafb_second_xres;
593 viamode.yres_sec = viafb_second_yres;
594 viamode.virtual_xres_sec = viafb_second_virtual_xres;
595 viamode.virtual_yres_sec = viafb_second_virtual_yres;
596 viamode.refresh_sec = viafb_refresh1;
597 viamode.bpp_sec = viafb_bpp1;
598 } else {
599 viamode.xres_sec = 0;
600 viamode.yres_sec = 0;
601 viamode.virtual_xres_sec = 0;
602 viamode.virtual_yres_sec = 0;
603 viamode.refresh_sec = 0;
604 viamode.bpp_sec = 0;
605 }
606 if (copy_to_user(argp, &viamode, sizeof(viamode)))
607 return -EFAULT;
608 break;
609 case VIAFB_GET_SAMM_INFO:
610 viasamm.samm_status = viafb_SAMM_ON;
611
612 if (viafb_SAMM_ON == 1) {
613 if (viafb_dual_fb) {
614 viasamm.size_prim = viaparinfo->fbmem_free;
615 viasamm.size_sec = viaparinfo1->fbmem_free;
616 } else {
617 if (viafb_second_size) {
618 viasamm.size_prim =
619 viaparinfo->fbmem_free -
620 viafb_second_size * 1024 * 1024;
621 viasamm.size_sec =
622 viafb_second_size * 1024 * 1024;
623 } else {
624 viasamm.size_prim =
625 viaparinfo->fbmem_free >> 1;
626 viasamm.size_sec =
627 (viaparinfo->fbmem_free >> 1);
628 }
629 }
630 viasamm.mem_base = viaparinfo->fbmem;
631 viasamm.offset_sec = viafb_second_offset;
632 } else {
633 viasamm.size_prim =
634 viaparinfo->memsize - viaparinfo->fbmem_used;
635 viasamm.size_sec = 0;
636 viasamm.mem_base = viaparinfo->fbmem;
637 viasamm.offset_sec = 0;
638 }
639
640 if (copy_to_user(argp, &viasamm, sizeof(viasamm)))
641 return -EFAULT;
642
643 break;
644 case VIAFB_TURN_ON_OUTPUT_DEVICE:
645 if (copy_from_user(&gpu32, argp, sizeof(gpu32)))
646 return -EFAULT;
647 if (gpu32 & CRT_Device)
648 viafb_crt_enable();
649 if (gpu32 & DVI_Device)
650 viafb_dvi_enable();
651 if (gpu32 & LCD_Device)
652 viafb_lcd_enable();
653 break;
654 case VIAFB_TURN_OFF_OUTPUT_DEVICE:
655 if (copy_from_user(&gpu32, argp, sizeof(gpu32)))
656 return -EFAULT;
657 if (gpu32 & CRT_Device)
658 viafb_crt_disable();
659 if (gpu32 & DVI_Device)
660 viafb_dvi_disable();
661 if (gpu32 & LCD_Device)
662 viafb_lcd_disable();
663 break;
664 case VIAFB_SET_DEVICE:
665 if (copy_from_user(&active_dev, (void *)argp,
666 sizeof(active_dev)))
667 return -EFAULT;
668 viafb_set_device(active_dev);
669 viafb_set_par(info);
670 break;
671 case VIAFB_GET_DEVICE:
672 active_dev.crt = viafb_CRT_ON;
673 active_dev.dvi = viafb_DVI_ON;
674 active_dev.lcd = viafb_LCD_ON;
675 active_dev.samm = viafb_SAMM_ON;
676 active_dev.primary_dev = viafb_primary_dev;
677
678 active_dev.lcd_dsp_cent = viafb_lcd_dsp_method;
679 active_dev.lcd_panel_id = viafb_lcd_panel_id;
680 active_dev.lcd_mode = viafb_lcd_mode;
681
682 active_dev.xres = viafb_hotplug_Xres;
683 active_dev.yres = viafb_hotplug_Yres;
684
685 active_dev.xres1 = viafb_second_xres;
686 active_dev.yres1 = viafb_second_yres;
687
688 active_dev.bpp = viafb_bpp;
689 active_dev.bpp1 = viafb_bpp1;
690 active_dev.refresh = viafb_refresh;
691 active_dev.refresh1 = viafb_refresh1;
692
693 active_dev.epia_dvi = viafb_platform_epia_dvi;
694 active_dev.lcd_dual_edge = viafb_device_lcd_dualedge;
695 active_dev.bus_width = viafb_bus_width;
696
697 if (copy_to_user(argp, &active_dev, sizeof(active_dev)))
698 return -EFAULT;
699 break;
700
701 case VIAFB_GET_DRIVER_VERSION:
702 driver_version.iMajorNum = VERSION_MAJOR;
703 driver_version.iKernelNum = VERSION_KERNEL;
704 driver_version.iOSNum = VERSION_OS;
705 driver_version.iMinorNum = VERSION_MINOR;
706
707 if (copy_to_user(argp, &driver_version,
708 sizeof(driver_version)))
709 return -EFAULT;
710
711 break;
712
713 case VIAFB_SET_DEVICE_INFO:
714 if (copy_from_user(&viafb_setting,
715 argp, sizeof(viafb_setting)))
716 return -EFAULT;
717 if (apply_device_setting(viafb_setting, info) < 0)
718 return -EINVAL;
719
720 break;
721
722 case VIAFB_SET_SECOND_MODE:
723 if (copy_from_user(&sec_var, argp, sizeof(sec_var)))
724 return -EFAULT;
725 apply_second_mode_setting(&sec_var);
726 break;
727
728 case VIAFB_GET_DEVICE_INFO:
729
730 retrieve_device_setting(&viafb_setting);
731
732 if (copy_to_user(argp, &viafb_setting, sizeof(viafb_setting)))
733 return -EFAULT;
734
735 break;
736
737 case VIAFB_GET_DEVICE_SUPPORT:
738 viafb_get_device_support_state(&state_info);
739 if (put_user(state_info, argp))
740 return -EFAULT;
741 break;
742
743 case VIAFB_GET_DEVICE_CONNECT:
744 viafb_get_device_connect_state(&state_info);
745 if (put_user(state_info, argp))
746 return -EFAULT;
747 break;
748
749 case VIAFB_GET_PANEL_SUPPORT_EXPAND:
750 state_info =
751 viafb_lcd_get_support_expand_state(info->var.xres,
752 info->var.yres);
753 if (put_user(state_info, argp))
754 return -EFAULT;
755 break;
756
757 case VIAFB_GET_DRIVER_NAME:
758 if (copy_to_user(argp, driver_name, sizeof(driver_name)))
759 return -EFAULT;
760 break;
761
762 case VIAFB_SET_GAMMA_LUT:
763 viafb_gamma_table = kmalloc(256 * sizeof(u32), GFP_KERNEL);
764 if (!viafb_gamma_table)
765 return -ENOMEM;
766 if (copy_from_user(viafb_gamma_table, argp,
767 sizeof(viafb_gamma_table))) {
768 kfree(viafb_gamma_table);
769 return -EFAULT;
770 }
771 viafb_set_gamma_table(viafb_bpp, viafb_gamma_table);
772 kfree(viafb_gamma_table);
773 break;
774
775 case VIAFB_GET_GAMMA_LUT:
776 viafb_gamma_table = kmalloc(256 * sizeof(u32), GFP_KERNEL);
777 if (!viafb_gamma_table)
778 return -ENOMEM;
779 viafb_get_gamma_table(viafb_gamma_table);
780 if (copy_to_user(argp, viafb_gamma_table,
781 sizeof(viafb_gamma_table))) {
782 kfree(viafb_gamma_table);
783 return -EFAULT;
784 }
785 kfree(viafb_gamma_table);
786 break;
787
788 case VIAFB_GET_GAMMA_SUPPORT_STATE:
789 viafb_get_gamma_support_state(viafb_bpp, &state_info);
790 if (put_user(state_info, argp))
791 return -EFAULT;
792 break;
793 case VIAFB_SET_VIDEO_DEVICE:
794 get_user(video_dev_info, argp);
795 viafb_set_video_device(video_dev_info);
796 break;
797 case VIAFB_GET_VIDEO_DEVICE:
798 viafb_get_video_device(&video_dev_info);
799 if (put_user(video_dev_info, argp))
800 return -EFAULT;
801 break;
802 case VIAFB_SYNC_SURFACE:
803 DEBUG_MSG(KERN_INFO "lobo VIAFB_SYNC_SURFACE\n");
804 break;
805 case VIAFB_GET_DRIVER_CAPS:
806 break;
807
808 case VIAFB_GET_PANEL_MAX_SIZE:
809 if (copy_from_user
810 (&panel_pos_size_para, argp, sizeof(panel_pos_size_para)))
811 return -EFAULT;
812 panel_pos_size_para.x = panel_pos_size_para.y = 0;
813 if (copy_to_user(argp, &panel_pos_size_para,
814 sizeof(panel_pos_size_para)))
815 return -EFAULT;
816 break;
817 case VIAFB_GET_PANEL_MAX_POSITION:
818 if (copy_from_user
819 (&panel_pos_size_para, argp, sizeof(panel_pos_size_para)))
820 return -EFAULT;
821 panel_pos_size_para.x = panel_pos_size_para.y = 0;
822 if (copy_to_user(argp, &panel_pos_size_para,
823 sizeof(panel_pos_size_para)))
824 return -EFAULT;
825 break;
826
827 case VIAFB_GET_PANEL_POSITION:
828 if (copy_from_user
829 (&panel_pos_size_para, argp, sizeof(panel_pos_size_para)))
830 return -EFAULT;
831 panel_pos_size_para.x = panel_pos_size_para.y = 0;
832 if (copy_to_user(argp, &panel_pos_size_para,
833 sizeof(panel_pos_size_para)))
834 return -EFAULT;
835 break;
836 case VIAFB_GET_PANEL_SIZE:
837 if (copy_from_user
838 (&panel_pos_size_para, argp, sizeof(panel_pos_size_para)))
839 return -EFAULT;
840 panel_pos_size_para.x = panel_pos_size_para.y = 0;
841 if (copy_to_user(argp, &panel_pos_size_para,
842 sizeof(panel_pos_size_para)))
843 return -EFAULT;
844 break;
845
846 case VIAFB_SET_PANEL_POSITION:
847 if (copy_from_user
848 (&panel_pos_size_para, argp, sizeof(panel_pos_size_para)))
849 return -EFAULT;
850 break;
851 case VIAFB_SET_PANEL_SIZE:
852 if (copy_from_user
853 (&panel_pos_size_para, argp, sizeof(panel_pos_size_para)))
854 return -EFAULT;
855 break;
856
857 default:
858 return -EINVAL;
859 }
860
861 return 0;
862}
863
864static void viafb_fillrect(struct fb_info *info,
865 const struct fb_fillrect *rect)
866{
867 u32 col = 0, rop = 0;
868 int pitch;
869
870 if (!viafb_accel)
871 return cfb_fillrect(info, rect);
872
873 if (!rect->width || !rect->height)
874 return;
875
876 switch (rect->rop) {
877 case ROP_XOR:
878 rop = 0x5A;
879 break;
880 case ROP_COPY:
881 default:
882 rop = 0xF0;
883 break;
884 }
885
886 switch (info->var.bits_per_pixel) {
887 case 8:
888 col = rect->color;
889 break;
890 case 16:
891 col = ((u32 *) (info->pseudo_palette))[rect->color];
892 break;
893 case 32:
894 col = ((u32 *) (info->pseudo_palette))[rect->color];
895 break;
896 }
897
898 /* BitBlt Source Address */
899 writel(0x0, viaparinfo->io_virt + VIA_REG_SRCPOS);
900 /* Source Base Address */
901 writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE);
902 /* Destination Base Address */
903 writel(((unsigned long) (info->screen_base) -
904 (unsigned long) viafb_FB_MM) >> 3,
905 viaparinfo->io_virt + VIA_REG_DSTBASE);
906 /* Pitch */
907 pitch = (info->var.xres_virtual + 7) & ~7;
908 writel(VIA_PITCH_ENABLE |
909 (((pitch *
910 info->var.bits_per_pixel >> 3) >> 3) |
911 (((pitch * info->
912 var.bits_per_pixel >> 3) >> 3) << 16)),
913 viaparinfo->io_virt + VIA_REG_PITCH);
914 /* BitBlt Destination Address */
915 writel(((rect->dy << 16) | rect->dx),
916 viaparinfo->io_virt + VIA_REG_DSTPOS);
917 /* Dimension: width & height */
918 writel((((rect->height - 1) << 16) | (rect->width - 1)),
919 viaparinfo->io_virt + VIA_REG_DIMENSION);
920 /* Forground color or Destination color */
921 writel(col, viaparinfo->io_virt + VIA_REG_FGCOLOR);
922 /* GE Command */
923 writel((0x01 | 0x2000 | (rop << 24)),
924 viaparinfo->io_virt + VIA_REG_GECMD);
925
926}
927
928static void viafb_copyarea(struct fb_info *info,
929 const struct fb_copyarea *area)
930{
931 u32 dy = area->dy, sy = area->sy, direction = 0x0;
932 u32 sx = area->sx, dx = area->dx, width = area->width;
933 int pitch;
934
935 DEBUG_MSG(KERN_INFO "viafb_copyarea!!\n");
936
937 if (!viafb_accel)
938 return cfb_copyarea(info, area);
939
940 if (!area->width || !area->height)
941 return;
942
943 if (sy < dy) {
944 dy += area->height - 1;
945 sy += area->height - 1;
946 direction |= 0x4000;
947 }
948
949 if (sx < dx) {
950 dx += width - 1;
951 sx += width - 1;
952 direction |= 0x8000;
953 }
954
955 /* Source Base Address */
956 writel(((unsigned long) (info->screen_base) -
957 (unsigned long) viafb_FB_MM) >> 3,
958 viaparinfo->io_virt + VIA_REG_SRCBASE);
959 /* Destination Base Address */
960 writel(((unsigned long) (info->screen_base) -
961 (unsigned long) viafb_FB_MM) >> 3,
962 viaparinfo->io_virt + VIA_REG_DSTBASE);
963 /* Pitch */
964 pitch = (info->var.xres_virtual + 7) & ~7;
965 /* VIA_PITCH_ENABLE can be omitted now. */
966 writel(VIA_PITCH_ENABLE |
967 (((pitch *
968 info->var.bits_per_pixel >> 3) >> 3) | (((pitch *
969 info->var.
970 bits_per_pixel
971 >> 3) >> 3)
972 << 16)),
973 viaparinfo->io_virt + VIA_REG_PITCH);
974 /* BitBlt Source Address */
975 writel(((sy << 16) | sx), viaparinfo->io_virt + VIA_REG_SRCPOS);
976 /* BitBlt Destination Address */
977 writel(((dy << 16) | dx), viaparinfo->io_virt + VIA_REG_DSTPOS);
978 /* Dimension: width & height */
979 writel((((area->height - 1) << 16) | (area->width - 1)),
980 viaparinfo->io_virt + VIA_REG_DIMENSION);
981 /* GE Command */
982 writel((0x01 | direction | (0xCC << 24)),
983 viaparinfo->io_virt + VIA_REG_GECMD);
984
985}
986
987static void viafb_imageblit(struct fb_info *info,
988 const struct fb_image *image)
989{
990 u32 size, bg_col = 0, fg_col = 0, *udata;
991 int i;
992 int pitch;
993
994 if (!viafb_accel)
995 return cfb_imageblit(info, image);
996
997 udata = (u32 *) image->data;
998
999 switch (info->var.bits_per_pixel) {
1000 case 8:
1001 bg_col = image->bg_color;
1002 fg_col = image->fg_color;
1003 break;
1004 case 16:
1005 bg_col = ((u32 *) (info->pseudo_palette))[image->bg_color];
1006 fg_col = ((u32 *) (info->pseudo_palette))[image->fg_color];
1007 break;
1008 case 32:
1009 bg_col = ((u32 *) (info->pseudo_palette))[image->bg_color];
1010 fg_col = ((u32 *) (info->pseudo_palette))[image->fg_color];
1011 break;
1012 }
1013 size = image->width * image->height;
1014
1015 /* Source Base Address */
1016 writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE);
1017 /* Destination Base Address */
1018 writel(((unsigned long) (info->screen_base) -
1019 (unsigned long) viafb_FB_MM) >> 3,
1020 viaparinfo->io_virt + VIA_REG_DSTBASE);
1021 /* Pitch */
1022 pitch = (info->var.xres_virtual + 7) & ~7;
1023 writel(VIA_PITCH_ENABLE |
1024 (((pitch *
1025 info->var.bits_per_pixel >> 3) >> 3) | (((pitch *
1026 info->var.
1027 bits_per_pixel
1028 >> 3) >> 3)
1029 << 16)),
1030 viaparinfo->io_virt + VIA_REG_PITCH);
1031 /* BitBlt Source Address */
1032 writel(0x0, viaparinfo->io_virt + VIA_REG_SRCPOS);
1033 /* BitBlt Destination Address */
1034 writel(((image->dy << 16) | image->dx),
1035 viaparinfo->io_virt + VIA_REG_DSTPOS);
1036 /* Dimension: width & height */
1037 writel((((image->height - 1) << 16) | (image->width - 1)),
1038 viaparinfo->io_virt + VIA_REG_DIMENSION);
1039 /* fb color */
1040 writel(fg_col, viaparinfo->io_virt + VIA_REG_FGCOLOR);
1041 /* bg color */
1042 writel(bg_col, viaparinfo->io_virt + VIA_REG_BGCOLOR);
1043 /* GE Command */
1044 writel(0xCC020142, viaparinfo->io_virt + VIA_REG_GECMD);
1045
1046 for (i = 0; i < size / 4; i++) {
1047 writel(*udata, viaparinfo->io_virt + VIA_MMIO_BLTBASE);
1048 udata++;
1049 }
1050
1051}
1052
1053static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1054{
1055 u8 data[CURSOR_SIZE / 8];
1056 u32 data_bak[CURSOR_SIZE / 32];
1057 u32 temp, xx, yy, bg_col = 0, fg_col = 0;
1058 int size, i, j = 0;
1059 static int hw_cursor;
1060 struct viafb_par *p_viafb_par;
1061
1062 if (viafb_accel)
1063 hw_cursor = 1;
1064
1065 if (!viafb_accel) {
1066 if (hw_cursor) {
1067 viafb_show_hw_cursor(info, HW_Cursor_OFF);
1068 hw_cursor = 0;
1069 }
1070 return -ENODEV;
1071 }
1072
1073 if ((((struct viafb_par *)(info->par))->iga_path == IGA2)
1074 && (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266))
1075 return -ENODEV;
1076
1077 /* When duoview and using lcd , use soft cursor */
1078 if (viafb_LCD_ON || ((struct viafb_par *)(info->par))->duoview)
1079 return -ENODEV;
1080
1081 viafb_show_hw_cursor(info, HW_Cursor_OFF);
1082 viacursor = *cursor;
1083
1084 if (cursor->set & FB_CUR_SETHOT) {
1085 viacursor.hot = cursor->hot;
1086 temp = ((viacursor.hot.x) << 16) + viacursor.hot.y;
1087 writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_ORG);
1088 }
1089
1090 if (cursor->set & FB_CUR_SETPOS) {
1091 viacursor.image.dx = cursor->image.dx;
1092 viacursor.image.dy = cursor->image.dy;
1093 yy = cursor->image.dy - info->var.yoffset;
1094 xx = cursor->image.dx - info->var.xoffset;
1095 temp = yy & 0xFFFF;
1096 temp |= (xx << 16);
1097 writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_POS);
1098 }
1099
1100 if (cursor->set & FB_CUR_SETSIZE) {
1101 temp = readl(viaparinfo->io_virt + VIA_REG_CURSOR_MODE);
1102
1103 if ((cursor->image.width <= 32)
1104 && (cursor->image.height <= 32)) {
1105 MAX_CURS = 32;
1106 temp |= 0x2;
1107 } else if ((cursor->image.width <= 64)
1108 && (cursor->image.height <= 64)) {
1109 MAX_CURS = 64;
1110 temp &= 0xFFFFFFFD;
1111 } else {
1112 DEBUG_MSG(KERN_INFO
1113 "The cursor image is biger than 64x64 bits...\n");
1114 return -ENXIO;
1115 }
1116 writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_MODE);
1117
1118 viacursor.image.height = cursor->image.height;
1119 viacursor.image.width = cursor->image.width;
1120 }
1121
1122 if (cursor->set & FB_CUR_SETCMAP) {
1123 viacursor.image.fg_color = cursor->image.fg_color;
1124 viacursor.image.bg_color = cursor->image.bg_color;
1125
1126 switch (info->var.bits_per_pixel) {
1127 case 8:
1128 case 16:
1129 case 32:
1130 bg_col =
1131 (0xFF << 24) |
1132 (((info->cmap.red)[viacursor.image.bg_color] &
1133 0xFF00) << 8) |
1134 ((info->cmap.green)[viacursor.image.bg_color] &
1135 0xFF00) |
1136 (((info->cmap.blue)[viacursor.image.bg_color] &
1137 0xFF00) >> 8);
1138 fg_col =
1139 (0xFF << 24) |
1140 (((info->cmap.red)[viacursor.image.fg_color] &
1141 0xFF00) << 8) |
1142 ((info->cmap.green)[viacursor.image.fg_color] &
1143 0xFF00) |
1144 (((info->cmap.blue)[viacursor.image.fg_color] &
1145 0xFF00) >> 8);
1146 break;
1147 default:
1148 return 0;
1149 }
1150
1151 /* This is indeed a patch for VT3324/VT3353 */
1152 if (!info->par)
1153 return 0;
1154 p_viafb_par = (struct viafb_par *)info->par;
1155
1156 if ((p_viafb_par->chip_info->gfx_chip_name ==
1157 UNICHROME_CX700) ||
1158 ((p_viafb_par->chip_info->gfx_chip_name ==
1159 UNICHROME_VX800))) {
1160 bg_col =
1161 (((info->cmap.red)[viacursor.image.bg_color] &
1162 0xFFC0) << 14) |
1163 (((info->cmap.green)[viacursor.image.bg_color] &
1164 0xFFC0) << 4) |
1165 (((info->cmap.blue)[viacursor.image.bg_color] &
1166 0xFFC0) >> 6);
1167 fg_col =
1168 (((info->cmap.red)[viacursor.image.fg_color] &
1169 0xFFC0) << 14) |
1170 (((info->cmap.green)[viacursor.image.fg_color] &
1171 0xFFC0) << 4) |
1172 (((info->cmap.blue)[viacursor.image.fg_color] &
1173 0xFFC0) >> 6);
1174 }
1175
1176 writel(bg_col, viaparinfo->io_virt + VIA_REG_CURSOR_BG);
1177 writel(fg_col, viaparinfo->io_virt + VIA_REG_CURSOR_FG);
1178 }
1179
1180 if (cursor->set & FB_CUR_SETSHAPE) {
1181 size =
1182 ((viacursor.image.width + 7) >> 3) *
1183 viacursor.image.height;
1184
1185 if (MAX_CURS == 32) {
1186 for (i = 0; i < (CURSOR_SIZE / 32); i++) {
1187 data_bak[i] = 0x0;
1188 data_bak[i + 1] = 0xFFFFFFFF;
1189 i += 1;
1190 }
1191 } else if (MAX_CURS == 64) {
1192 for (i = 0; i < (CURSOR_SIZE / 32); i++) {
1193 data_bak[i] = 0x0;
1194 data_bak[i + 1] = 0x0;
1195 data_bak[i + 2] = 0xFFFFFFFF;
1196 data_bak[i + 3] = 0xFFFFFFFF;
1197 i += 3;
1198 }
1199 }
1200
1201 switch (viacursor.rop) {
1202 case ROP_XOR:
1203 for (i = 0; i < size; i++)
1204 data[i] = viacursor.mask[i];
1205 break;
1206 case ROP_COPY:
1207
1208 for (i = 0; i < size; i++)
1209 data[i] = viacursor.mask[i];
1210 break;
1211 default:
1212 break;
1213 }
1214
1215 if (MAX_CURS == 32) {
1216 for (i = 0; i < size; i++) {
1217 data_bak[j] = (u32) data[i];
1218 data_bak[j + 1] = ~data_bak[j];
1219 j += 2;
1220 }
1221 } else if (MAX_CURS == 64) {
1222 for (i = 0; i < size; i++) {
1223 data_bak[j] = (u32) data[i];
1224 data_bak[j + 1] = 0x0;
1225 data_bak[j + 2] = ~data_bak[j];
1226 data_bak[j + 3] = ~data_bak[j + 1];
1227 j += 4;
1228 }
1229 }
1230
1231 memcpy(((struct viafb_par *)(info->par))->fbmem_virt +
1232 ((struct viafb_par *)(info->par))->cursor_start,
1233 data_bak, CURSOR_SIZE);
1234 }
1235
1236 if (viacursor.enable)
1237 viafb_show_hw_cursor(info, HW_Cursor_ON);
1238
1239 return 0;
1240}
1241
1242static int viafb_sync(struct fb_info *info)
1243{
1244 if (viafb_accel)
1245 viafb_wait_engine_idle();
1246 return 0;
1247}
1248
1249int viafb_get_mode_index(int hres, int vres, int flag)
1250{
1251 u32 i;
1252 DEBUG_MSG(KERN_INFO "viafb_get_mode_index!\n");
1253
1254 for (i = 0; viafb_modentry[i].mode_index != VIA_RES_INVALID; i++)
1255 if (viafb_modentry[i].xres == hres &&
1256 viafb_modentry[i].yres == vres)
1257 break;
1258
1259 viafb_resMode = viafb_modentry[i].mode_index;
1260 if (flag)
1261 viafb_mode1 = viafb_modentry[i].mode_res;
1262 else
1263 viafb_mode = viafb_modentry[i].mode_res;
1264
1265 return viafb_resMode;
1266}
1267
1268static void check_available_device_to_enable(int device_id)
1269{
1270 int device_num = 0;
1271
1272 /* Initialize: */
1273 viafb_CRT_ON = STATE_OFF;
1274 viafb_DVI_ON = STATE_OFF;
1275 viafb_LCD_ON = STATE_OFF;
1276 viafb_LCD2_ON = STATE_OFF;
1277 viafb_DeviceStatus = None_Device;
1278
1279 if ((device_id & CRT_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) {
1280 viafb_CRT_ON = STATE_ON;
1281 device_num++;
1282 viafb_DeviceStatus |= CRT_Device;
1283 }
1284
1285 if ((device_id & DVI_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) {
1286 viafb_DVI_ON = STATE_ON;
1287 device_num++;
1288 viafb_DeviceStatus |= DVI_Device;
1289 }
1290
1291 if ((device_id & LCD_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) {
1292 viafb_LCD_ON = STATE_ON;
1293 device_num++;
1294 viafb_DeviceStatus |= LCD_Device;
1295 }
1296
1297 if ((device_id & LCD2_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) {
1298 viafb_LCD2_ON = STATE_ON;
1299 device_num++;
1300 viafb_DeviceStatus |= LCD2_Device;
1301 }
1302
1303 if (viafb_DeviceStatus == None_Device) {
1304 /* Use CRT as default active device: */
1305 viafb_CRT_ON = STATE_ON;
1306 viafb_DeviceStatus = CRT_Device;
1307 }
1308 DEBUG_MSG(KERN_INFO "Device Status:%x", viafb_DeviceStatus);
1309}
1310
1311static void viafb_set_device(struct device_t active_dev)
1312{
1313 /* Check available device to enable: */
1314 int device_id = None_Device;
1315 if (active_dev.crt)
1316 device_id |= CRT_Device;
1317 if (active_dev.dvi)
1318 device_id |= DVI_Device;
1319 if (active_dev.lcd)
1320 device_id |= LCD_Device;
1321
1322 check_available_device_to_enable(device_id);
1323
1324 /* Check property of LCD: */
1325 if (viafb_LCD_ON) {
1326 if (active_dev.lcd_dsp_cent) {
1327 viaparinfo->lvds_setting_info->display_method =
1328 viafb_lcd_dsp_method = LCD_CENTERING;
1329 } else {
1330 viaparinfo->lvds_setting_info->display_method =
1331 viafb_lcd_dsp_method = LCD_EXPANDSION;
1332 }
1333
1334 if (active_dev.lcd_mode == LCD_SPWG) {
1335 viaparinfo->lvds_setting_info->lcd_mode =
1336 viafb_lcd_mode = LCD_SPWG;
1337 } else {
1338 viaparinfo->lvds_setting_info->lcd_mode =
1339 viafb_lcd_mode = LCD_OPENLDI;
1340 }
1341
1342 if (active_dev.lcd_panel_id <= LCD_PANEL_ID_MAXIMUM) {
1343 viafb_lcd_panel_id = active_dev.lcd_panel_id;
1344 viafb_init_lcd_size();
1345 }
1346 }
1347
1348 /* Check property of mode: */
1349 if (!active_dev.xres1)
1350 viafb_second_xres = 640;
1351 else
1352 viafb_second_xres = active_dev.xres1;
1353 if (!active_dev.yres1)
1354 viafb_second_yres = 480;
1355 else
1356 viafb_second_yres = active_dev.yres1;
1357 if (active_dev.bpp != 0)
1358 viafb_bpp = active_dev.bpp;
1359 if (active_dev.bpp1 != 0)
1360 viafb_bpp1 = active_dev.bpp1;
1361 if (active_dev.refresh != 0)
1362 viafb_refresh = active_dev.refresh;
1363 if (active_dev.refresh1 != 0)
1364 viafb_refresh1 = active_dev.refresh1;
1365 if ((active_dev.samm == STATE_OFF) || (active_dev.samm == STATE_ON))
1366 viafb_SAMM_ON = active_dev.samm;
1367 viafb_primary_dev = active_dev.primary_dev;
1368
1369 viafb_set_start_addr();
1370 viafb_set_iga_path();
1371}
1372
1373static void viafb_set_video_device(u32 video_dev_info)
1374{
1375 viaparinfo->video_on_crt = STATE_OFF;
1376 viaparinfo->video_on_dvi = STATE_OFF;
1377 viaparinfo->video_on_lcd = STATE_OFF;
1378
1379 /* Check available device to enable: */
1380 if ((video_dev_info & CRT_Device) == CRT_Device)
1381 viaparinfo->video_on_crt = STATE_ON;
1382 else if ((video_dev_info & DVI_Device) == DVI_Device)
1383 viaparinfo->video_on_dvi = STATE_ON;
1384 else if ((video_dev_info & LCD_Device) == LCD_Device)
1385 viaparinfo->video_on_lcd = STATE_ON;
1386}
1387
1388static void viafb_get_video_device(u32 *video_dev_info)
1389{
1390 *video_dev_info = None_Device;
1391 if (viaparinfo->video_on_crt == STATE_ON)
1392 *video_dev_info |= CRT_Device;
1393 else if (viaparinfo->video_on_dvi == STATE_ON)
1394 *video_dev_info |= DVI_Device;
1395 else if (viaparinfo->video_on_lcd == STATE_ON)
1396 *video_dev_info |= LCD_Device;
1397}
1398
1399static int get_primary_device(void)
1400{
1401 int primary_device = 0;
1402 /* Rule: device on iga1 path are the primary device. */
1403 if (viafb_SAMM_ON) {
1404 if (viafb_CRT_ON) {
1405 if (viaparinfo->crt_setting_info->iga_path == IGA1) {
1406 DEBUG_MSG(KERN_INFO "CRT IGA Path:%d\n",
1407 viaparinfo->
1408 crt_setting_info->iga_path);
1409 primary_device = CRT_Device;
1410 }
1411 }
1412 if (viafb_DVI_ON) {
1413 if (viaparinfo->tmds_setting_info->iga_path == IGA1) {
1414 DEBUG_MSG(KERN_INFO "DVI IGA Path:%d\n",
1415 viaparinfo->
1416 tmds_setting_info->iga_path);
1417 primary_device = DVI_Device;
1418 }
1419 }
1420 if (viafb_LCD_ON) {
1421 if (viaparinfo->lvds_setting_info->iga_path == IGA1) {
1422 DEBUG_MSG(KERN_INFO "LCD IGA Path:%d\n",
1423 viaparinfo->
1424 lvds_setting_info->iga_path);
1425 primary_device = LCD_Device;
1426 }
1427 }
1428 if (viafb_LCD2_ON) {
1429 if (viaparinfo->lvds_setting_info2->iga_path == IGA1) {
1430 DEBUG_MSG(KERN_INFO "LCD2 IGA Path:%d\n",
1431 viaparinfo->
1432 lvds_setting_info2->iga_path);
1433 primary_device = LCD2_Device;
1434 }
1435 }
1436 }
1437 return primary_device;
1438}
1439
1440static u8 is_duoview(void)
1441{
1442 if (0 == viafb_SAMM_ON) {
1443 if (viafb_LCD_ON + viafb_LCD2_ON +
1444 viafb_DVI_ON + viafb_CRT_ON == 2)
1445 return true;
1446 return false;
1447 } else {
1448 return false;
1449 }
1450}
1451
1452static void apply_second_mode_setting(struct fb_var_screeninfo
1453 *sec_var)
1454{
1455 u32 htotal, vtotal, long_refresh;
1456
1457 htotal = sec_var->xres + sec_var->left_margin +
1458 sec_var->right_margin + sec_var->hsync_len;
1459 vtotal = sec_var->yres + sec_var->upper_margin +
1460 sec_var->lower_margin + sec_var->vsync_len;
1461 if ((sec_var->xres_virtual * (sec_var->bits_per_pixel >> 3)) & 0x1F) {
1462 /*Is 32 bytes alignment? */
1463 /*32 pixel alignment */
1464 sec_var->xres_virtual = (sec_var->xres_virtual + 31) & ~31;
1465 }
1466
1467 htotal = sec_var->xres + sec_var->left_margin +
1468 sec_var->right_margin + sec_var->hsync_len;
1469 vtotal = sec_var->yres + sec_var->upper_margin +
1470 sec_var->lower_margin + sec_var->vsync_len;
1471 long_refresh = 1000000000UL / sec_var->pixclock * 1000;
1472 long_refresh /= (htotal * vtotal);
1473
1474 viafb_second_xres = sec_var->xres;
1475 viafb_second_yres = sec_var->yres;
1476 viafb_second_virtual_xres = sec_var->xres_virtual;
1477 viafb_second_virtual_yres = sec_var->yres_virtual;
1478 viafb_bpp1 = sec_var->bits_per_pixel;
1479 viafb_refresh1 = viafb_get_refresh(sec_var->xres, sec_var->yres,
1480 long_refresh);
1481}
1482
1483static int apply_device_setting(struct viafb_ioctl_setting setting_info,
1484 struct fb_info *info)
1485{
1486 int need_set_mode = 0;
1487 DEBUG_MSG(KERN_INFO "apply_device_setting\n");
1488
1489 if (setting_info.device_flag) {
1490 need_set_mode = 1;
1491 check_available_device_to_enable(setting_info.device_status);
1492 }
1493
1494 /* Unlock LCD's operation according to LCD flag
1495 and check if the setting value is valid. */
1496 /* If the value is valid, apply the new setting value to the device. */
1497 if (viafb_LCD_ON) {
1498 if (setting_info.lcd_operation_flag & OP_LCD_CENTERING) {
1499 need_set_mode = 1;
1500 if (setting_info.lcd_attributes.display_center) {
1501 /* Centering */
1502 viaparinfo->lvds_setting_info->display_method =
1503 LCD_CENTERING;
1504 viafb_lcd_dsp_method = LCD_CENTERING;
1505 viaparinfo->lvds_setting_info2->display_method =
1506 viafb_lcd_dsp_method = LCD_CENTERING;
1507 } else {
1508 /* expandsion */
1509 viaparinfo->lvds_setting_info->display_method =
1510 LCD_EXPANDSION;
1511 viafb_lcd_dsp_method = LCD_EXPANDSION;
1512 viaparinfo->lvds_setting_info2->display_method =
1513 LCD_EXPANDSION;
1514 viafb_lcd_dsp_method = LCD_EXPANDSION;
1515 }
1516 }
1517
1518 if (setting_info.lcd_operation_flag & OP_LCD_MODE) {
1519 need_set_mode = 1;
1520 if (setting_info.lcd_attributes.lcd_mode ==
1521 LCD_SPWG) {
1522 viaparinfo->lvds_setting_info->lcd_mode =
1523 viafb_lcd_mode = LCD_SPWG;
1524 } else {
1525 viaparinfo->lvds_setting_info->lcd_mode =
1526 viafb_lcd_mode = LCD_OPENLDI;
1527 }
1528 viaparinfo->lvds_setting_info2->lcd_mode =
1529 viaparinfo->lvds_setting_info->lcd_mode;
1530 }
1531
1532 if (setting_info.lcd_operation_flag & OP_LCD_PANEL_ID) {
1533 need_set_mode = 1;
1534 if (setting_info.lcd_attributes.panel_id <=
1535 LCD_PANEL_ID_MAXIMUM) {
1536 viafb_lcd_panel_id =
1537 setting_info.lcd_attributes.panel_id;
1538 viafb_init_lcd_size();
1539 }
1540 }
1541 }
1542
1543 if (0 != (setting_info.samm_status & OP_SAMM)) {
1544 setting_info.samm_status =
1545 setting_info.samm_status & (~OP_SAMM);
1546 if (setting_info.samm_status == 0
1547 || setting_info.samm_status == 1) {
1548 viafb_SAMM_ON = setting_info.samm_status;
1549
1550 if (viafb_SAMM_ON)
1551 viafb_primary_dev = setting_info.primary_device;
1552
1553 viafb_set_start_addr();
1554 viafb_set_iga_path();
1555 }
1556 need_set_mode = 1;
1557 }
1558
1559 viaparinfo->duoview = is_duoview();
1560
1561 if (!need_set_mode) {
1562 ;
1563 } else {
1564 viafb_set_iga_path();
1565 viafb_set_par(info);
1566 }
1567 return true;
1568}
1569
1570static void retrieve_device_setting(struct viafb_ioctl_setting
1571 *setting_info)
1572{
1573
1574 /* get device status */
1575 if (viafb_CRT_ON == 1)
1576 setting_info->device_status = CRT_Device;
1577 if (viafb_DVI_ON == 1)
1578 setting_info->device_status |= DVI_Device;
1579 if (viafb_LCD_ON == 1)
1580 setting_info->device_status |= LCD_Device;
1581 if (viafb_LCD2_ON == 1)
1582 setting_info->device_status |= LCD2_Device;
1583 if ((viaparinfo->video_on_crt == 1) && (viafb_CRT_ON == 1)) {
1584 setting_info->video_device_status =
1585 viaparinfo->crt_setting_info->iga_path;
1586 } else if ((viaparinfo->video_on_dvi == 1) && (viafb_DVI_ON == 1)) {
1587 setting_info->video_device_status =
1588 viaparinfo->tmds_setting_info->iga_path;
1589 } else if ((viaparinfo->video_on_lcd == 1) && (viafb_LCD_ON == 1)) {
1590 setting_info->video_device_status =
1591 viaparinfo->lvds_setting_info->iga_path;
1592 } else {
1593 setting_info->video_device_status = 0;
1594 }
1595
1596 setting_info->samm_status = viafb_SAMM_ON;
1597 setting_info->primary_device = get_primary_device();
1598
1599 setting_info->first_dev_bpp = viafb_bpp;
1600 setting_info->second_dev_bpp = viafb_bpp1;
1601
1602 setting_info->first_dev_refresh = viafb_refresh;
1603 setting_info->second_dev_refresh = viafb_refresh1;
1604
1605 setting_info->first_dev_hor_res = viafb_hotplug_Xres;
1606 setting_info->first_dev_ver_res = viafb_hotplug_Yres;
1607 setting_info->second_dev_hor_res = viafb_second_xres;
1608 setting_info->second_dev_ver_res = viafb_second_yres;
1609
1610 /* Get lcd attributes */
1611 setting_info->lcd_attributes.display_center = viafb_lcd_dsp_method;
1612 setting_info->lcd_attributes.panel_id = viafb_lcd_panel_id;
1613 setting_info->lcd_attributes.lcd_mode = viafb_lcd_mode;
1614}
1615
1616static void parse_active_dev(void)
1617{
1618 viafb_CRT_ON = STATE_OFF;
1619 viafb_DVI_ON = STATE_OFF;
1620 viafb_LCD_ON = STATE_OFF;
1621 viafb_LCD2_ON = STATE_OFF;
1622 /* 1. Modify the active status of devices. */
1623 /* 2. Keep the order of devices, so we can set corresponding
1624 IGA path to devices in SAMM case. */
1625 /* Note: The previous of active_dev is primary device,
1626 and the following is secondary device. */
1627 if (!strncmp(viafb_active_dev, "CRT+DVI", 7)) {
1628 /* CRT+DVI */
1629 viafb_CRT_ON = STATE_ON;
1630 viafb_DVI_ON = STATE_ON;
1631 viafb_primary_dev = CRT_Device;
1632 } else if (!strncmp(viafb_active_dev, "DVI+CRT", 7)) {
1633 /* DVI+CRT */
1634 viafb_CRT_ON = STATE_ON;
1635 viafb_DVI_ON = STATE_ON;
1636 viafb_primary_dev = DVI_Device;
1637 } else if (!strncmp(viafb_active_dev, "CRT+LCD", 7)) {
1638 /* CRT+LCD */
1639 viafb_CRT_ON = STATE_ON;
1640 viafb_LCD_ON = STATE_ON;
1641 viafb_primary_dev = CRT_Device;
1642 } else if (!strncmp(viafb_active_dev, "LCD+CRT", 7)) {
1643 /* LCD+CRT */
1644 viafb_CRT_ON = STATE_ON;
1645 viafb_LCD_ON = STATE_ON;
1646 viafb_primary_dev = LCD_Device;
1647 } else if (!strncmp(viafb_active_dev, "DVI+LCD", 7)) {
1648 /* DVI+LCD */
1649 viafb_DVI_ON = STATE_ON;
1650 viafb_LCD_ON = STATE_ON;
1651 viafb_primary_dev = DVI_Device;
1652 } else if (!strncmp(viafb_active_dev, "LCD+DVI", 7)) {
1653 /* LCD+DVI */
1654 viafb_DVI_ON = STATE_ON;
1655 viafb_LCD_ON = STATE_ON;
1656 viafb_primary_dev = LCD_Device;
1657 } else if (!strncmp(viafb_active_dev, "LCD+LCD2", 8)) {
1658 viafb_LCD_ON = STATE_ON;
1659 viafb_LCD2_ON = STATE_ON;
1660 viafb_primary_dev = LCD_Device;
1661 } else if (!strncmp(viafb_active_dev, "LCD2+LCD", 8)) {
1662 viafb_LCD_ON = STATE_ON;
1663 viafb_LCD2_ON = STATE_ON;
1664 viafb_primary_dev = LCD2_Device;
1665 } else if (!strncmp(viafb_active_dev, "CRT", 3)) {
1666 /* CRT only */
1667 viafb_CRT_ON = STATE_ON;
1668 viafb_SAMM_ON = STATE_OFF;
1669 } else if (!strncmp(viafb_active_dev, "DVI", 3)) {
1670 /* DVI only */
1671 viafb_DVI_ON = STATE_ON;
1672 viafb_SAMM_ON = STATE_OFF;
1673 } else if (!strncmp(viafb_active_dev, "LCD", 3)) {
1674 /* LCD only */
1675 viafb_LCD_ON = STATE_ON;
1676 viafb_SAMM_ON = STATE_OFF;
1677 } else {
1678 viafb_CRT_ON = STATE_ON;
1679 viafb_SAMM_ON = STATE_OFF;
1680 }
1681 viaparinfo->duoview = is_duoview();
1682}
1683
1684static void parse_video_dev(void)
1685{
1686 viaparinfo->video_on_crt = STATE_OFF;
1687 viaparinfo->video_on_dvi = STATE_OFF;
1688 viaparinfo->video_on_lcd = STATE_OFF;
1689
1690 if (!strncmp(viafb_video_dev, "CRT", 3)) {
1691 /* Video on CRT */
1692 viaparinfo->video_on_crt = STATE_ON;
1693 } else if (!strncmp(viafb_video_dev, "DVI", 3)) {
1694 /* Video on DVI */
1695 viaparinfo->video_on_dvi = STATE_ON;
1696 } else if (!strncmp(viafb_video_dev, "LCD", 3)) {
1697 /* Video on LCD */
1698 viaparinfo->video_on_lcd = STATE_ON;
1699 }
1700}
1701
1702static int parse_port(char *opt_str, int *output_interface)
1703{
1704 if (!strncmp(opt_str, "DVP0", 4))
1705 *output_interface = INTERFACE_DVP0;
1706 else if (!strncmp(opt_str, "DVP1", 4))
1707 *output_interface = INTERFACE_DVP1;
1708 else if (!strncmp(opt_str, "DFP_HIGHLOW", 11))
1709 *output_interface = INTERFACE_DFP;
1710 else if (!strncmp(opt_str, "DFP_HIGH", 8))
1711 *output_interface = INTERFACE_DFP_HIGH;
1712 else if (!strncmp(opt_str, "DFP_LOW", 7))
1713 *output_interface = INTERFACE_DFP_LOW;
1714 else
1715 *output_interface = INTERFACE_NONE;
1716 return 0;
1717}
1718
1719static void parse_lcd_port(void)
1720{
1721 parse_port(viafb_lcd_port, &viaparinfo->chip_info->lvds_chip_info.
1722 output_interface);
1723 /*Initialize to avoid unexpected behavior */
1724 viaparinfo->chip_info->lvds_chip_info2.output_interface =
1725 INTERFACE_NONE;
1726
1727 DEBUG_MSG(KERN_INFO "parse_lcd_port: viafb_lcd_port:%s,interface:%d\n",
1728 viafb_lcd_port, viaparinfo->chip_info->lvds_chip_info.
1729 output_interface);
1730}
1731
1732static void parse_dvi_port(void)
1733{
1734 parse_port(viafb_dvi_port, &viaparinfo->chip_info->tmds_chip_info.
1735 output_interface);
1736
1737 DEBUG_MSG(KERN_INFO "parse_dvi_port: viafb_dvi_port:%s,interface:%d\n",
1738 viafb_dvi_port, viaparinfo->chip_info->tmds_chip_info.
1739 output_interface);
1740}
1741
1742/*
1743 * The proc filesystem read/write function, a simple proc implement to
1744 * get/set the value of DPA DVP0, DVP0DataDriving, DVP0ClockDriving, DVP1,
1745 * DVP1Driving, DFPHigh, DFPLow CR96, SR2A[5], SR1B[1], SR2A[4], SR1E[2],
1746 * CR9B, SR65, CR97, CR99
1747 */
1748static int viafb_dvp0_proc_read(char *buf, char **start, off_t offset,
1749int count, int *eof, void *data)
1750{
1751 int len = 0;
1752 u8 dvp0_data_dri = 0, dvp0_clk_dri = 0, dvp0 = 0;
1753 dvp0_data_dri =
1754 (viafb_read_reg(VIASR, SR2A) & BIT5) >> 4 |
1755 (viafb_read_reg(VIASR, SR1B) & BIT1) >> 1;
1756 dvp0_clk_dri =
1757 (viafb_read_reg(VIASR, SR2A) & BIT4) >> 3 |
1758 (viafb_read_reg(VIASR, SR1E) & BIT2) >> 2;
1759 dvp0 = viafb_read_reg(VIACR, CR96) & 0x0f;
1760 len +=
1761 sprintf(buf + len, "%x %x %x\n", dvp0, dvp0_data_dri, dvp0_clk_dri);
1762 *eof = 1; /*Inform kernel end of data */
1763 return len;
1764}
1765static int viafb_dvp0_proc_write(struct file *file,
1766 const char __user *buffer, unsigned long count, void *data)
1767{
1768 char buf[20], *value, *pbuf;
1769 u8 reg_val = 0;
1770 unsigned long length, i;
1771 if (count < 1)
1772 return -EINVAL;
1773 length = count > 20 ? 20 : count;
1774 if (copy_from_user(&buf[0], buffer, length))
1775 return -EFAULT;
1776 buf[length - 1] = '\0'; /*Ensure end string */
1777 pbuf = &buf[0];
1778 for (i = 0; i < 3; i++) {
1779 value = strsep(&pbuf, " ");
1780 if (value != NULL) {
1781 strict_strtoul(value, 0, (unsigned long *)&reg_val);
1782 DEBUG_MSG(KERN_INFO "DVP0:reg_val[%l]=:%x\n", i,
1783 reg_val);
1784 switch (i) {
1785 case 0:
1786 viafb_write_reg_mask(CR96, VIACR,
1787 reg_val, 0x0f);
1788 break;
1789 case 1:
1790 viafb_write_reg_mask(SR2A, VIASR,
1791 reg_val << 4, BIT5);
1792 viafb_write_reg_mask(SR1B, VIASR,
1793 reg_val << 1, BIT1);
1794 break;
1795 case 2:
1796 viafb_write_reg_mask(SR2A, VIASR,
1797 reg_val << 3, BIT4);
1798 viafb_write_reg_mask(SR1E, VIASR,
1799 reg_val << 2, BIT2);
1800 break;
1801 default:
1802 break;
1803 }
1804 } else {
1805 break;
1806 }
1807 }
1808 return count;
1809}
1810static int viafb_dvp1_proc_read(char *buf, char **start, off_t offset,
1811 int count, int *eof, void *data)
1812{
1813 int len = 0;
1814 u8 dvp1 = 0, dvp1_data_dri = 0, dvp1_clk_dri = 0;
1815 dvp1 = viafb_read_reg(VIACR, CR9B) & 0x0f;
1816 dvp1_data_dri = (viafb_read_reg(VIASR, SR65) & 0x0c) >> 2;
1817 dvp1_clk_dri = viafb_read_reg(VIASR, SR65) & 0x03;
1818 len +=
1819 sprintf(buf + len, "%x %x %x\n", dvp1, dvp1_data_dri, dvp1_clk_dri);
1820 *eof = 1; /*Inform kernel end of data */
1821 return len;
1822}
1823static int viafb_dvp1_proc_write(struct file *file,
1824 const char __user *buffer, unsigned long count, void *data)
1825{
1826 char buf[20], *value, *pbuf;
1827 u8 reg_val = 0;
1828 unsigned long length, i;
1829 if (count < 1)
1830 return -EINVAL;
1831 length = count > 20 ? 20 : count;
1832 if (copy_from_user(&buf[0], buffer, length))
1833 return -EFAULT;
1834 buf[length - 1] = '\0'; /*Ensure end string */
1835 pbuf = &buf[0];
1836 for (i = 0; i < 3; i++) {
1837 value = strsep(&pbuf, " ");
1838 if (value != NULL) {
1839 strict_strtoul(value, 0, (unsigned long *)&reg_val);
1840 switch (i) {
1841 case 0:
1842 viafb_write_reg_mask(CR9B, VIACR,
1843 reg_val, 0x0f);
1844 break;
1845 case 1:
1846 viafb_write_reg_mask(SR65, VIASR,
1847 reg_val << 2, 0x0c);
1848 break;
1849 case 2:
1850 viafb_write_reg_mask(SR65, VIASR,
1851 reg_val, 0x03);
1852 break;
1853 default:
1854 break;
1855 }
1856 } else {
1857 break;
1858 }
1859 }
1860 return count;
1861}
1862
1863static int viafb_dfph_proc_read(char *buf, char **start, off_t offset,
1864 int count, int *eof, void *data)
1865{
1866 int len = 0;
1867 u8 dfp_high = 0;
1868 dfp_high = viafb_read_reg(VIACR, CR97) & 0x0f;
1869 len += sprintf(buf + len, "%x\n", dfp_high);
1870 *eof = 1; /*Inform kernel end of data */
1871 return len;
1872}
1873static int viafb_dfph_proc_write(struct file *file,
1874 const char __user *buffer, unsigned long count, void *data)
1875{
1876 char buf[20];
1877 u8 reg_val = 0;
1878 unsigned long length;
1879 if (count < 1)
1880 return -EINVAL;
1881 length = count > 20 ? 20 : count;
1882 if (copy_from_user(&buf[0], buffer, length))
1883 return -EFAULT;
1884 buf[length - 1] = '\0'; /*Ensure end string */
1885 strict_strtoul(&buf[0], 0, (unsigned long *)&reg_val);
1886 viafb_write_reg_mask(CR97, VIACR, reg_val, 0x0f);
1887 return count;
1888}
1889static int viafb_dfpl_proc_read(char *buf, char **start, off_t offset,
1890 int count, int *eof, void *data)
1891{
1892 int len = 0;
1893 u8 dfp_low = 0;
1894 dfp_low = viafb_read_reg(VIACR, CR99) & 0x0f;
1895 len += sprintf(buf + len, "%x\n", dfp_low);
1896 *eof = 1; /*Inform kernel end of data */
1897 return len;
1898}
1899static int viafb_dfpl_proc_write(struct file *file,
1900 const char __user *buffer, unsigned long count, void *data)
1901{
1902 char buf[20];
1903 u8 reg_val = 0;
1904 unsigned long length;
1905 if (count < 1)
1906 return -EINVAL;
1907 length = count > 20 ? 20 : count;
1908 if (copy_from_user(&buf[0], buffer, length))
1909 return -EFAULT;
1910 buf[length - 1] = '\0'; /*Ensure end string */
1911 strict_strtoul(&buf[0], 0, (unsigned long *)&reg_val);
1912 viafb_write_reg_mask(CR99, VIACR, reg_val, 0x0f);
1913 return count;
1914}
1915static int viafb_vt1636_proc_read(char *buf, char **start,
1916 off_t offset, int count, int *eof, void *data)
1917{
1918 int len = 0;
1919 u8 vt1636_08 = 0, vt1636_09 = 0;
1920 switch (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
1921 case VT1636_LVDS:
1922 vt1636_08 =
1923 viafb_gpio_i2c_read_lvds(viaparinfo->lvds_setting_info,
1924 &viaparinfo->chip_info->lvds_chip_info, 0x08) & 0x0f;
1925 vt1636_09 =
1926 viafb_gpio_i2c_read_lvds(viaparinfo->lvds_setting_info,
1927 &viaparinfo->chip_info->lvds_chip_info, 0x09) & 0x1f;
1928 len += sprintf(buf + len, "%x %x\n", vt1636_08, vt1636_09);
1929 break;
1930 default:
1931 break;
1932 }
1933 switch (viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) {
1934 case VT1636_LVDS:
1935 vt1636_08 =
1936 viafb_gpio_i2c_read_lvds(viaparinfo->lvds_setting_info2,
1937 &viaparinfo->chip_info->lvds_chip_info2, 0x08) & 0x0f;
1938 vt1636_09 =
1939 viafb_gpio_i2c_read_lvds(viaparinfo->lvds_setting_info2,
1940 &viaparinfo->chip_info->lvds_chip_info2, 0x09) & 0x1f;
1941 len += sprintf(buf + len, " %x %x\n", vt1636_08, vt1636_09);
1942 break;
1943 default:
1944 break;
1945 }
1946 *eof = 1; /*Inform kernel end of data */
1947 return len;
1948}
1949static int viafb_vt1636_proc_write(struct file *file,
1950 const char __user *buffer, unsigned long count, void *data)
1951{
1952 char buf[30], *value, *pbuf;
1953 struct IODATA reg_val;
1954 unsigned long length, i;
1955 if (count < 1)
1956 return -EINVAL;
1957 length = count > 30 ? 30 : count;
1958 if (copy_from_user(&buf[0], buffer, length))
1959 return -EFAULT;
1960 buf[length - 1] = '\0'; /*Ensure end string */
1961 pbuf = &buf[0];
1962 switch (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
1963 case VT1636_LVDS:
1964 for (i = 0; i < 2; i++) {
1965 value = strsep(&pbuf, " ");
1966 if (value != NULL) {
1967 strict_strtoul(value, 0,
1968 (unsigned long *)&reg_val.Data);
1969 switch (i) {
1970 case 0:
1971 reg_val.Index = 0x08;
1972 reg_val.Mask = 0x0f;
1973 viafb_gpio_i2c_write_mask_lvds
1974 (viaparinfo->lvds_setting_info,
1975 &viaparinfo->
1976 chip_info->lvds_chip_info,
1977 reg_val);
1978 break;
1979 case 1:
1980 reg_val.Index = 0x09;
1981 reg_val.Mask = 0x1f;
1982 viafb_gpio_i2c_write_mask_lvds
1983 (viaparinfo->lvds_setting_info,
1984 &viaparinfo->
1985 chip_info->lvds_chip_info,
1986 reg_val);
1987 break;
1988 default:
1989 break;
1990 }
1991 } else {
1992 break;
1993 }
1994 }
1995 break;
1996 default:
1997 break;
1998 }
1999 switch (viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) {
2000 case VT1636_LVDS:
2001 for (i = 0; i < 2; i++) {
2002 value = strsep(&pbuf, " ");
2003 if (value != NULL) {
2004 strict_strtoul(value, 0,
2005 (unsigned long *)&reg_val.Data);
2006 switch (i) {
2007 case 0:
2008 reg_val.Index = 0x08;
2009 reg_val.Mask = 0x0f;
2010 viafb_gpio_i2c_write_mask_lvds
2011 (viaparinfo->lvds_setting_info2,
2012 &viaparinfo->
2013 chip_info->lvds_chip_info2,
2014 reg_val);
2015 break;
2016 case 1:
2017 reg_val.Index = 0x09;
2018 reg_val.Mask = 0x1f;
2019 viafb_gpio_i2c_write_mask_lvds
2020 (viaparinfo->lvds_setting_info2,
2021 &viaparinfo->
2022 chip_info->lvds_chip_info2,
2023 reg_val);
2024 break;
2025 default:
2026 break;
2027 }
2028 } else {
2029 break;
2030 }
2031 }
2032 break;
2033 default:
2034 break;
2035 }
2036 return count;
2037}
2038
2039static void viafb_init_proc(struct proc_dir_entry *viafb_entry)
2040{
2041 struct proc_dir_entry *entry;
2042 viafb_entry = proc_mkdir("viafb", NULL);
2043 if (viafb_entry) {
2044 entry = create_proc_entry("dvp0", 0, viafb_entry);
2045 if (entry) {
2046 entry->owner = THIS_MODULE;
2047 entry->read_proc = viafb_dvp0_proc_read;
2048 entry->write_proc = viafb_dvp0_proc_write;
2049 }
2050 entry = create_proc_entry("dvp1", 0, viafb_entry);
2051 if (entry) {
2052 entry->owner = THIS_MODULE;
2053 entry->read_proc = viafb_dvp1_proc_read;
2054 entry->write_proc = viafb_dvp1_proc_write;
2055 }
2056 entry = create_proc_entry("dfph", 0, viafb_entry);
2057 if (entry) {
2058 entry->owner = THIS_MODULE;
2059 entry->read_proc = viafb_dfph_proc_read;
2060 entry->write_proc = viafb_dfph_proc_write;
2061 }
2062 entry = create_proc_entry("dfpl", 0, viafb_entry);
2063 if (entry) {
2064 entry->owner = THIS_MODULE;
2065 entry->read_proc = viafb_dfpl_proc_read;
2066 entry->write_proc = viafb_dfpl_proc_write;
2067 }
2068 if (VT1636_LVDS == viaparinfo->chip_info->lvds_chip_info.
2069 lvds_chip_name || VT1636_LVDS ==
2070 viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) {
2071 entry = create_proc_entry("vt1636", 0, viafb_entry);
2072 if (entry) {
2073 entry->owner = THIS_MODULE;
2074 entry->read_proc = viafb_vt1636_proc_read;
2075 entry->write_proc = viafb_vt1636_proc_write;
2076 }
2077 }
2078
2079 }
2080}
2081static void viafb_remove_proc(struct proc_dir_entry *viafb_entry)
2082{
2083 /* no problem if it was not registered */
2084 remove_proc_entry("dvp0", viafb_entry);/* parent dir */
2085 remove_proc_entry("dvp1", viafb_entry);
2086 remove_proc_entry("dfph", viafb_entry);
2087 remove_proc_entry("dfpl", viafb_entry);
2088 remove_proc_entry("vt1636", viafb_entry);
2089 remove_proc_entry("vt1625", viafb_entry);
2090}
2091
2092static int __devinit via_pci_probe(void)
2093{
2094 unsigned int default_xres, default_yres;
2095 char *tmpc, *tmpm;
2096 char *tmpc_sec, *tmpm_sec;
2097 int vmode_index;
2098 u32 tmds_length, lvds_length, crt_length, chip_length, viafb_par_length;
2099
2100 DEBUG_MSG(KERN_INFO "VIAFB PCI Probe!!\n");
2101
2102 viafb_par_length = ALIGN(sizeof(struct viafb_par), BITS_PER_LONG/8);
2103 tmds_length = ALIGN(sizeof(struct tmds_setting_information),
2104 BITS_PER_LONG/8);
2105 lvds_length = ALIGN(sizeof(struct lvds_setting_information),
2106 BITS_PER_LONG/8);
2107 crt_length = ALIGN(sizeof(struct lvds_setting_information),
2108 BITS_PER_LONG/8);
2109 chip_length = ALIGN(sizeof(struct chip_information), BITS_PER_LONG/8);
2110
2111 /* Allocate fb_info and ***_par here, also including some other needed
2112 * variables
2113 */
2114 viafbinfo = framebuffer_alloc(viafb_par_length + 2 * lvds_length +
2115 tmds_length + crt_length + chip_length, NULL);
2116 if (!viafbinfo) {
2117 printk(KERN_ERR"Could not allocate memory for viafb_info.\n");
2118 return -ENODEV;
2119 }
2120
2121 viaparinfo = (struct viafb_par *)viafbinfo->par;
2122 viaparinfo->tmds_setting_info = (struct tmds_setting_information *)
2123 ((unsigned long)viaparinfo + viafb_par_length);
2124 viaparinfo->lvds_setting_info = (struct lvds_setting_information *)
2125 ((unsigned long)viaparinfo->tmds_setting_info + tmds_length);
2126 viaparinfo->lvds_setting_info2 = (struct lvds_setting_information *)
2127 ((unsigned long)viaparinfo->lvds_setting_info + lvds_length);
2128 viaparinfo->crt_setting_info = (struct crt_setting_information *)
2129 ((unsigned long)viaparinfo->lvds_setting_info2 + lvds_length);
2130 viaparinfo->chip_info = (struct chip_information *)
2131 ((unsigned long)viaparinfo->crt_setting_info + crt_length);
2132
2133 if (viafb_dual_fb)
2134 viafb_SAMM_ON = 1;
2135 parse_active_dev();
2136 parse_video_dev();
2137 parse_lcd_port();
2138 parse_dvi_port();
2139
2140 /* for dual-fb must viafb_SAMM_ON=1 and viafb_dual_fb=1 */
2141 if (!viafb_SAMM_ON)
2142 viafb_dual_fb = 0;
2143
2144 /* Set up I2C bus stuff */
2145 viafb_create_i2c_bus(viaparinfo);
2146
2147 viafb_init_chip_info();
2148 viafb_get_fb_info(&viaparinfo->fbmem, &viaparinfo->memsize);
2149 viaparinfo->fbmem_free = viaparinfo->memsize;
2150 viaparinfo->fbmem_used = 0;
2151 viaparinfo->fbmem_virt = ioremap_nocache(viaparinfo->fbmem,
2152 viaparinfo->memsize);
2153 viafbinfo->screen_base = (char *)viaparinfo->fbmem_virt;
2154
2155 if (!viaparinfo->fbmem_virt) {
2156 printk(KERN_INFO "ioremap failed\n");
2157 return -1;
2158 }
2159
2160 viafb_get_mmio_info(&viaparinfo->mmio_base, &viaparinfo->mmio_len);
2161 viaparinfo->io_virt = ioremap_nocache(viaparinfo->mmio_base,
2162 viaparinfo->mmio_len);
2163
2164 viafbinfo->node = 0;
2165 viafbinfo->fbops = &viafb_ops;
2166 viafbinfo->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
2167
2168 viafbinfo->pseudo_palette = pseudo_pal;
2169 if (viafb_accel) {
2170 viafb_init_accel();
2171 viafb_init_2d_engine();
2172 viafb_hw_cursor_init();
2173 }
2174
2175 if (viafb_second_size && (viafb_second_size < 8)) {
2176 viafb_second_offset = viaparinfo->fbmem_free -
2177 viafb_second_size * 1024 * 1024;
2178 } else {
2179 viafb_second_size = 8;
2180 viafb_second_offset = viaparinfo->fbmem_free -
2181 viafb_second_size * 1024 * 1024;
2182 }
2183
2184 viafb_FB_MM = viaparinfo->fbmem_virt;
2185 tmpm = viafb_mode;
2186 tmpc = strsep(&tmpm, "x");
2187 strict_strtoul(tmpc, 0, (unsigned long *)&default_xres);
2188 strict_strtoul(tmpm, 0, (unsigned long *)&default_yres);
2189
2190 vmode_index = viafb_get_mode_index(default_xres, default_yres, 0);
2191 DEBUG_MSG(KERN_INFO "0->index=%d\n", vmode_index);
2192
2193 if (viafb_SAMM_ON == 1) {
2194 if (strcmp(viafb_mode, viafb_mode1)) {
2195 tmpm_sec = viafb_mode1;
2196 tmpc_sec = strsep(&tmpm_sec, "x");
2197 strict_strtoul(tmpc_sec, 0,
2198 (unsigned long *)&viafb_second_xres);
2199 strict_strtoul(tmpm_sec, 0,
2200 (unsigned long *)&viafb_second_yres);
2201 } else {
2202 viafb_second_xres = default_xres;
2203 viafb_second_yres = default_yres;
2204 }
2205 if (0 == viafb_second_virtual_xres) {
2206 switch (viafb_second_xres) {
2207 case 1400:
2208 viafb_second_virtual_xres = 1408;
2209 break;
2210 default:
2211 viafb_second_virtual_xres = viafb_second_xres;
2212 break;
2213 }
2214 }
2215 if (0 == viafb_second_virtual_yres)
2216 viafb_second_virtual_yres = viafb_second_yres;
2217 }
2218
2219 switch (viafb_bpp) {
2220 case 0 ... 8:
2221 viafb_bpp = 8;
2222 break;
2223 case 9 ... 16:
2224 viafb_bpp = 16;
2225 break;
2226 case 17 ... 32:
2227 viafb_bpp = 32;
2228 break;
2229 default:
2230 viafb_bpp = 8;
2231 }
2232 default_var.xres = default_xres;
2233 default_var.yres = default_yres;
2234 switch (default_xres) {
2235 case 1400:
2236 default_var.xres_virtual = 1408;
2237 break;
2238 default:
2239 default_var.xres_virtual = default_xres;
2240 break;
2241 }
2242 default_var.yres_virtual = default_yres;
2243 default_var.bits_per_pixel = viafb_bpp;
2244 if (default_var.bits_per_pixel == 15)
2245 default_var.bits_per_pixel = 16;
2246 default_var.pixclock =
2247 viafb_get_pixclock(default_xres, default_yres, viafb_refresh);
2248 default_var.left_margin = (default_xres >> 3) & 0xf8;
2249 default_var.right_margin = 32;
2250 default_var.upper_margin = 16;
2251 default_var.lower_margin = 4;
2252 default_var.hsync_len = default_var.left_margin;
2253 default_var.vsync_len = 4;
2254 default_var.accel_flags = 0;
2255
2256 if (viafb_accel) {
2257 viafbinfo->flags |=
2258 (FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT |
2259 FBINFO_HWACCEL_IMAGEBLIT);
2260 default_var.accel_flags |= FB_ACCELF_TEXT;
2261 } else
2262 viafbinfo->flags |= FBINFO_HWACCEL_DISABLED;
2263
2264 if (viafb_dual_fb) {
2265 viafbinfo1 = framebuffer_alloc(viafb_par_length, NULL);
2266 if (!viafbinfo1) {
2267 printk(KERN_ERR
2268 "allocate the second framebuffer struct error\n");
2269 framebuffer_release(viafbinfo);
2270 return -ENOMEM;
2271 }
2272 viaparinfo1 = viafbinfo1->par;
2273 memcpy(viaparinfo1, viaparinfo, viafb_par_length);
2274 viaparinfo1->memsize = viaparinfo->memsize -
2275 viafb_second_offset;
2276 viaparinfo->memsize = viafb_second_offset;
2277 viaparinfo1->fbmem_virt = viaparinfo->fbmem_virt +
2278 viafb_second_offset;
2279 viaparinfo1->fbmem = viaparinfo->fbmem + viafb_second_offset;
2280
2281 viaparinfo1->fbmem_used = viaparinfo->fbmem_used;
2282 viaparinfo1->fbmem_free = viaparinfo1->memsize -
2283 viaparinfo1->fbmem_used;
2284 viaparinfo->fbmem_free = viaparinfo->memsize;
2285 viaparinfo->fbmem_used = 0;
2286 if (viafb_accel) {
2287 viaparinfo1->cursor_start =
2288 viaparinfo->cursor_start - viafb_second_offset;
2289 viaparinfo1->VQ_start = viaparinfo->VQ_start -
2290 viafb_second_offset;
2291 viaparinfo1->VQ_end = viaparinfo->VQ_end -
2292 viafb_second_offset;
2293 }
2294
2295 memcpy(viafbinfo1, viafbinfo, sizeof(struct fb_info));
2296 viafbinfo1->screen_base = viafbinfo->screen_base +
2297 viafb_second_offset;
2298 viafbinfo1->fix.smem_start = viaparinfo1->fbmem;
2299 viafbinfo1->fix.smem_len = viaparinfo1->fbmem_free;
2300
2301 default_var.xres = viafb_second_xres;
2302 default_var.yres = viafb_second_yres;
2303 default_var.xres_virtual = viafb_second_virtual_xres;
2304 default_var.yres_virtual = viafb_second_virtual_yres;
2305 if (viafb_bpp1 != viafb_bpp)
2306 viafb_bpp1 = viafb_bpp;
2307 default_var.bits_per_pixel = viafb_bpp1;
2308 default_var.pixclock =
2309 viafb_get_pixclock(viafb_second_xres, viafb_second_yres,
2310 viafb_refresh);
2311 default_var.left_margin = (viafb_second_xres >> 3) & 0xf8;
2312 default_var.right_margin = 32;
2313 default_var.upper_margin = 16;
2314 default_var.lower_margin = 4;
2315 default_var.hsync_len = default_var.left_margin;
2316 default_var.vsync_len = 4;
2317
2318 viafb_setup_fixinfo(&viafbinfo1->fix, viaparinfo1);
2319 viafb_check_var(&default_var, viafbinfo1);
2320 viafbinfo1->var = default_var;
2321 viafb_update_viafb_par(viafbinfo);
2322 viafb_update_fix(&viafbinfo1->fix, viafbinfo1);
2323 }
2324
2325 viafb_setup_fixinfo(&viafbinfo->fix, viaparinfo);
2326 viafb_check_var(&default_var, viafbinfo);
2327 viafbinfo->var = default_var;
2328 viafb_update_viafb_par(viafbinfo);
2329 viafb_update_fix(&viafbinfo->fix, viafbinfo);
2330 default_var.activate = FB_ACTIVATE_NOW;
2331 fb_alloc_cmap(&viafbinfo->cmap, 256, 0);
2332
2333 if (viafb_dual_fb && (viafb_primary_dev == LCD_Device)
2334 && (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)) {
2335 if (register_framebuffer(viafbinfo1) < 0)
2336 return -EINVAL;
2337 }
2338 if (register_framebuffer(viafbinfo) < 0)
2339 return -EINVAL;
2340
2341 if (viafb_dual_fb && ((viafb_primary_dev != LCD_Device)
2342 || (viaparinfo->chip_info->gfx_chip_name !=
2343 UNICHROME_CLE266))) {
2344 if (register_framebuffer(viafbinfo1) < 0)
2345 return -EINVAL;
2346 }
2347 DEBUG_MSG(KERN_INFO "fb%d: %s frame buffer device %dx%d-%dbpp\n",
2348 viafbinfo->node, viafbinfo->fix.id, default_var.xres,
2349 default_var.yres, default_var.bits_per_pixel);
2350
2351 viafb_init_proc(viaparinfo->proc_entry);
2352 viafb_init_dac(IGA2);
2353 return 0;
2354}
2355
2356static void __devexit via_pci_remove(void)
2357{
2358 DEBUG_MSG(KERN_INFO "via_pci_remove!\n");
2359 fb_dealloc_cmap(&viafbinfo->cmap);
2360 unregister_framebuffer(viafbinfo);
2361 if (viafb_dual_fb)
2362 unregister_framebuffer(viafbinfo1);
2363 iounmap((void *)viaparinfo->fbmem_virt);
2364 iounmap(viaparinfo->io_virt);
2365
2366 viafb_delete_i2c_buss(viaparinfo);
2367
2368 framebuffer_release(viafbinfo);
2369 if (viafb_dual_fb)
2370 framebuffer_release(viafbinfo1);
2371
2372 viafb_remove_proc(viaparinfo->proc_entry);
2373}
2374
2375#ifndef MODULE
2376static int __init viafb_setup(char *options)
2377{
2378 char *this_opt;
2379 DEBUG_MSG(KERN_INFO "viafb_setup!\n");
2380
2381 if (!options || !*options)
2382 return 0;
2383
2384 while ((this_opt = strsep(&options, ",")) != NULL) {
2385 if (!*this_opt)
2386 continue;
2387
2388 if (!strncmp(this_opt, "viafb_mode1=", 12))
2389 viafb_mode1 = kstrdup(this_opt + 12, GFP_KERNEL);
2390 else if (!strncmp(this_opt, "viafb_mode=", 11))
2391 viafb_mode = kstrdup(this_opt + 11, GFP_KERNEL);
2392 else if (!strncmp(this_opt, "viafb_bpp1=", 11))
2393 strict_strtoul(this_opt + 11, 0,
2394 (unsigned long *)&viafb_bpp1);
2395 else if (!strncmp(this_opt, "viafb_bpp=", 10))
2396 strict_strtoul(this_opt + 10, 0,
2397 (unsigned long *)&viafb_bpp);
2398 else if (!strncmp(this_opt, "viafb_refresh1=", 15))
2399 strict_strtoul(this_opt + 15, 0,
2400 (unsigned long *)&viafb_refresh1);
2401 else if (!strncmp(this_opt, "viafb_refresh=", 14))
2402 strict_strtoul(this_opt + 14, 0,
2403 (unsigned long *)&viafb_refresh);
2404 else if (!strncmp(this_opt, "viafb_lcd_dsp_method=", 21))
2405 strict_strtoul(this_opt + 21, 0,
2406 (unsigned long *)&viafb_lcd_dsp_method);
2407 else if (!strncmp(this_opt, "viafb_lcd_panel_id=", 19))
2408 strict_strtoul(this_opt + 19, 0,
2409 (unsigned long *)&viafb_lcd_panel_id);
2410 else if (!strncmp(this_opt, "viafb_accel=", 12))
2411 strict_strtoul(this_opt + 12, 0,
2412 (unsigned long *)&viafb_accel);
2413 else if (!strncmp(this_opt, "viafb_SAMM_ON=", 14))
2414 strict_strtoul(this_opt + 14, 0,
2415 (unsigned long *)&viafb_SAMM_ON);
2416 else if (!strncmp(this_opt, "viafb_active_dev=", 17))
2417 viafb_active_dev = kstrdup(this_opt + 17, GFP_KERNEL);
2418 else if (!strncmp(this_opt,
2419 "viafb_display_hardware_layout=", 30))
2420 strict_strtoul(this_opt + 30, 0,
2421 (unsigned long *)&viafb_display_hardware_layout);
2422 else if (!strncmp(this_opt, "viafb_second_size=", 18))
2423 strict_strtoul(this_opt + 18, 0,
2424 (unsigned long *)&viafb_second_size);
2425 else if (!strncmp(this_opt,
2426 "viafb_platform_epia_dvi=", 24))
2427 strict_strtoul(this_opt + 24, 0,
2428 (unsigned long *)&viafb_platform_epia_dvi);
2429 else if (!strncmp(this_opt,
2430 "viafb_device_lcd_dualedge=", 26))
2431 strict_strtoul(this_opt + 26, 0,
2432 (unsigned long *)&viafb_device_lcd_dualedge);
2433 else if (!strncmp(this_opt, "viafb_bus_width=", 16))
2434 strict_strtoul(this_opt + 16, 0,
2435 (unsigned long *)&viafb_bus_width);
2436 else if (!strncmp(this_opt, "viafb_lcd_mode=", 15))
2437 strict_strtoul(this_opt + 15, 0,
2438 (unsigned long *)&viafb_lcd_mode);
2439 else if (!strncmp(this_opt, "viafb_video_dev=", 16))
2440 viafb_video_dev = kstrdup(this_opt + 16, GFP_KERNEL);
2441 else if (!strncmp(this_opt, "viafb_lcd_port=", 15))
2442 viafb_lcd_port = kstrdup(this_opt + 15, GFP_KERNEL);
2443 else if (!strncmp(this_opt, "viafb_dvi_port=", 15))
2444 viafb_dvi_port = kstrdup(this_opt + 15, GFP_KERNEL);
2445 }
2446 return 0;
2447}
2448#endif
2449
2450static int __init viafb_init(void)
2451{
2452#ifndef MODULE
2453 char *option = NULL;
2454 if (fb_get_options("viafb", &option))
2455 return -ENODEV;
2456 viafb_setup(option);
2457#endif
2458 printk(KERN_INFO
2459 "VIA Graphics Intergration Chipset framebuffer %d.%d initializing\n",
2460 VERSION_MAJOR, VERSION_MINOR);
2461 return via_pci_probe();
2462}
2463
2464static void __exit viafb_exit(void)
2465{
2466 DEBUG_MSG(KERN_INFO "viafb_exit!\n");
2467 via_pci_remove();
2468}
2469
2470static struct fb_ops viafb_ops = {
2471 .owner = THIS_MODULE,
2472 .fb_open = viafb_open,
2473 .fb_release = viafb_release,
2474 .fb_check_var = viafb_check_var,
2475 .fb_set_par = viafb_set_par,
2476 .fb_setcolreg = viafb_setcolreg,
2477 .fb_pan_display = viafb_pan_display,
2478 .fb_blank = viafb_blank,
2479 .fb_fillrect = viafb_fillrect,
2480 .fb_copyarea = viafb_copyarea,
2481 .fb_imageblit = viafb_imageblit,
2482 .fb_cursor = viafb_cursor,
2483 .fb_ioctl = viafb_ioctl,
2484 .fb_sync = viafb_sync,
2485 .fb_setcmap = viafb_setcmap,
2486};
2487
2488module_init(viafb_init);
2489module_exit(viafb_exit);
2490
2491#ifdef MODULE
2492module_param(viafb_memsize, int, 0);
2493
2494module_param(viafb_mode, charp, 0);
2495MODULE_PARM_DESC(viafb_mode, "Set resolution (default=640x480)");
2496
2497module_param(viafb_mode1, charp, 0);
2498MODULE_PARM_DESC(viafb_mode1, "Set resolution (default=640x480)");
2499
2500module_param(viafb_bpp, int, 0);
2501MODULE_PARM_DESC(viafb_bpp, "Set color depth (default=32bpp)");
2502
2503module_param(viafb_bpp1, int, 0);
2504MODULE_PARM_DESC(viafb_bpp1, "Set color depth (default=32bpp)");
2505
2506module_param(viafb_refresh, int, 0);
2507MODULE_PARM_DESC(viafb_refresh,
2508 "Set CRT viafb_refresh rate (default = 60)");
2509
2510module_param(viafb_refresh1, int, 0);
2511MODULE_PARM_DESC(viafb_refresh1,
2512 "Set CRT refresh rate (default = 60)");
2513
2514module_param(viafb_lcd_panel_id, int, 0);
2515MODULE_PARM_DESC(viafb_lcd_panel_id,
2516 "Set Flat Panel type(Default=1024x768)");
2517
2518module_param(viafb_lcd_dsp_method, int, 0);
2519MODULE_PARM_DESC(viafb_lcd_dsp_method,
2520 "Set Flat Panel display scaling method.(Default=Expandsion)");
2521
2522module_param(viafb_SAMM_ON, int, 0);
2523MODULE_PARM_DESC(viafb_SAMM_ON,
2524 "Turn on/off flag of SAMM(Default=OFF)");
2525
2526module_param(viafb_accel, int, 0);
2527MODULE_PARM_DESC(viafb_accel,
2528 "Set 2D Hardware Acceleration.(Default = OFF)");
2529
2530module_param(viafb_active_dev, charp, 0);
2531MODULE_PARM_DESC(viafb_active_dev, "Specify active devices.");
2532
2533module_param(viafb_display_hardware_layout, int, 0);
2534MODULE_PARM_DESC(viafb_display_hardware_layout,
2535 "Display Hardware Layout (LCD Only, DVI Only...,etc)");
2536
2537module_param(viafb_second_size, int, 0);
2538MODULE_PARM_DESC(viafb_second_size,
2539 "Set secondary device memory size");
2540
2541module_param(viafb_dual_fb, int, 0);
2542MODULE_PARM_DESC(viafb_dual_fb,
2543 "Turn on/off flag of dual framebuffer devices.(Default = OFF)");
2544
2545module_param(viafb_platform_epia_dvi, int, 0);
2546MODULE_PARM_DESC(viafb_platform_epia_dvi,
2547 "Turn on/off flag of DVI devices on EPIA board.(Default = OFF)");
2548
2549module_param(viafb_device_lcd_dualedge, int, 0);
2550MODULE_PARM_DESC(viafb_device_lcd_dualedge,
2551 "Turn on/off flag of dual edge panel.(Default = OFF)");
2552
2553module_param(viafb_bus_width, int, 0);
2554MODULE_PARM_DESC(viafb_bus_width,
2555 "Set bus width of panel.(Default = 12)");
2556
2557module_param(viafb_lcd_mode, int, 0);
2558MODULE_PARM_DESC(viafb_lcd_mode,
2559 "Set Flat Panel mode(Default=OPENLDI)");
2560
2561module_param(viafb_video_dev, charp, 0);
2562MODULE_PARM_DESC(viafb_video_dev, "Specify video devices.");
2563
2564module_param(viafb_lcd_port, charp, 0);
2565MODULE_PARM_DESC(viafb_lcd_port, "Specify LCD output port.");
2566
2567module_param(viafb_dvi_port, charp, 0);
2568MODULE_PARM_DESC(viafb_dvi_port, "Specify DVI output port.");
2569
2570MODULE_LICENSE("GPL");
2571#endif
diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h
new file mode 100644
index 000000000000..a4158e872878
--- /dev/null
+++ b/drivers/video/via/viafbdev.h
@@ -0,0 +1,112 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
14 * for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22#ifndef __VIAFBDEV_H__
23#define __VIAFBDEV_H__
24
25#include <linux/proc_fs.h>
26#include <linux/fb.h>
27
28#include "ioctl.h"
29#include "share.h"
30#include "chip.h"
31#include "hw.h"
32#include "via_i2c.h"
33
34#define VERSION_MAJOR 2
35#define VERSION_KERNEL 6 /* For kernel 2.6 */
36
37#define VERSION_OS 0 /* 0: for 32 bits OS, 1: for 64 bits OS */
38#define VERSION_MINOR 4
39
40struct viafb_par {
41 int bpp;
42 int hres;
43 int vres;
44 int linelength;
45 u32 xoffset;
46 u32 yoffset;
47
48 void __iomem *fbmem_virt; /*framebuffer virtual memory address */
49 void __iomem *io_virt; /*iospace virtual memory address */
50 unsigned int fbmem; /*framebuffer physical memory address */
51 unsigned int memsize; /*size of fbmem */
52 unsigned int io; /*io space address */
53 unsigned long mmio_base; /*mmio base address */
54 unsigned long mmio_len; /*mmio base length */
55 u32 fbmem_free; /* Free FB memory */
56 u32 fbmem_used; /* Use FB memory size */
57 u32 cursor_start; /* Cursor Start Address */
58 u32 VQ_start; /* Virtual Queue Start Address */
59 u32 VQ_end; /* Virtual Queue End Address */
60 u32 iga_path;
61 struct proc_dir_entry *proc_entry; /*viafb proc entry */
62 u8 duoview; /*Is working in duoview mode? */
63
64 /* I2C stuff */
65 struct via_i2c_stuff i2c_stuff;
66
67 /* All the information will be needed to set engine */
68 struct tmds_setting_information *tmds_setting_info;
69 struct crt_setting_information *crt_setting_info;
70 struct lvds_setting_information *lvds_setting_info;
71 struct lvds_setting_information *lvds_setting_info2;
72 struct chip_information *chip_info;
73
74 /* some information related to video playing */
75 int video_on_crt;
76 int video_on_dvi;
77 int video_on_lcd;
78
79};
80struct viafb_modeinfo {
81 u32 xres;
82 u32 yres;
83 int mode_index;
84 char *mode_res;
85};
86extern unsigned int viafb_second_virtual_yres;
87extern unsigned int viafb_second_virtual_xres;
88extern unsigned int viafb_second_offset;
89extern int viafb_second_size;
90extern int viafb_SAMM_ON;
91extern int viafb_dual_fb;
92extern int viafb_LCD2_ON;
93extern int viafb_LCD_ON;
94extern int viafb_DVI_ON;
95extern int viafb_accel;
96extern int viafb_hotplug;
97extern int viafb_memsize;
98
99extern int strict_strtoul(const char *cp, unsigned int base,
100 unsigned long *res);
101
102void viafb_memory_pitch_patch(struct fb_info *info);
103void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh,
104 int mode_index);
105int viafb_get_mode_index(int hres, int vres, int flag);
106u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information
107 *plvds_setting_info, struct lvds_chip_information
108 *plvds_chip_info, u8 index);
109void viafb_gpio_i2c_write_mask_lvds(struct lvds_setting_information
110 *plvds_setting_info, struct lvds_chip_information
111 *plvds_chip_info, struct IODATA io_data);
112#endif /* __VIAFBDEV_H__ */
diff --git a/drivers/video/via/viamode.c b/drivers/video/via/viamode.c
new file mode 100644
index 000000000000..6dcf583a837d
--- /dev/null
+++ b/drivers/video/via/viamode.c
@@ -0,0 +1,1086 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
14 * for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22#include "global.h"
23struct res_map_refresh res_map_refresh_tbl[] = {
24/*hres, vres, vclock, vmode_refresh*/
25 {480, 640, RES_480X640_60HZ_PIXCLOCK, 60},
26 {640, 480, RES_640X480_60HZ_PIXCLOCK, 60},
27 {640, 480, RES_640X480_75HZ_PIXCLOCK, 75},
28 {640, 480, RES_640X480_85HZ_PIXCLOCK, 85},
29 {640, 480, RES_640X480_100HZ_PIXCLOCK, 100},
30 {640, 480, RES_640X480_120HZ_PIXCLOCK, 120},
31 {720, 480, RES_720X480_60HZ_PIXCLOCK, 60},
32 {720, 576, RES_720X576_60HZ_PIXCLOCK, 60},
33 {800, 480, RES_800X480_60HZ_PIXCLOCK, 60},
34 {800, 600, RES_800X600_60HZ_PIXCLOCK, 60},
35 {800, 600, RES_800X600_75HZ_PIXCLOCK, 75},
36 {800, 600, RES_800X600_85HZ_PIXCLOCK, 85},
37 {800, 600, RES_800X600_100HZ_PIXCLOCK, 100},
38 {800, 600, RES_800X600_120HZ_PIXCLOCK, 120},
39 {848, 480, RES_848X480_60HZ_PIXCLOCK, 60},
40 {856, 480, RES_856X480_60HZ_PIXCLOCK, 60},
41 {1024, 512, RES_1024X512_60HZ_PIXCLOCK, 60},
42 {1024, 600, RES_1024X600_60HZ_PIXCLOCK, 60},
43 {1024, 768, RES_1024X768_60HZ_PIXCLOCK, 60},
44 {1024, 768, RES_1024X768_75HZ_PIXCLOCK, 75},
45 {1024, 768, RES_1024X768_85HZ_PIXCLOCK, 85},
46 {1024, 768, RES_1024X768_100HZ_PIXCLOCK, 100},
47/* {1152,864, RES_1152X864_70HZ_PIXCLOCK, 70},*/
48 {1152, 864, RES_1152X864_75HZ_PIXCLOCK, 75},
49 {1280, 768, RES_1280X768_60HZ_PIXCLOCK, 60},
50 {1280, 800, RES_1280X800_60HZ_PIXCLOCK, 60},
51 {1280, 960, RES_1280X960_60HZ_PIXCLOCK, 60},
52 {1280, 1024, RES_1280X1024_60HZ_PIXCLOCK, 60},
53 {1280, 1024, RES_1280X1024_75HZ_PIXCLOCK, 75},
54 {1280, 1024, RES_1280X768_85HZ_PIXCLOCK, 85},
55 {1440, 1050, RES_1440X1050_60HZ_PIXCLOCK, 60},
56 {1600, 1200, RES_1600X1200_60HZ_PIXCLOCK, 60},
57 {1600, 1200, RES_1600X1200_75HZ_PIXCLOCK, 75},
58 {1280, 720, RES_1280X720_60HZ_PIXCLOCK, 60},
59 {1920, 1080, RES_1920X1080_60HZ_PIXCLOCK, 60},
60 {1400, 1050, RES_1400X1050_60HZ_PIXCLOCK, 60},
61 {1400, 1050, RES_1400X1050_75HZ_PIXCLOCK, 75},
62 {1368, 768, RES_1368X768_60HZ_PIXCLOCK, 60},
63 {960, 600, RES_960X600_60HZ_PIXCLOCK, 60},
64 {1000, 600, RES_1000X600_60HZ_PIXCLOCK, 60},
65 {1024, 576, RES_1024X576_60HZ_PIXCLOCK, 60},
66 {1088, 612, RES_1088X612_60HZ_PIXCLOCK, 60},
67 {1152, 720, RES_1152X720_60HZ_PIXCLOCK, 60},
68 {1200, 720, RES_1200X720_60HZ_PIXCLOCK, 60},
69 {1280, 600, RES_1280X600_60HZ_PIXCLOCK, 60},
70 {1280, 720, RES_1280X720_50HZ_PIXCLOCK, 50},
71 {1280, 768, RES_1280X768_50HZ_PIXCLOCK, 50},
72 {1360, 768, RES_1360X768_60HZ_PIXCLOCK, 60},
73 {1366, 768, RES_1366X768_50HZ_PIXCLOCK, 50},
74 {1366, 768, RES_1366X768_60HZ_PIXCLOCK, 60},
75 {1440, 900, RES_1440X900_60HZ_PIXCLOCK, 60},
76 {1440, 900, RES_1440X900_75HZ_PIXCLOCK, 75},
77 {1600, 900, RES_1600X900_60HZ_PIXCLOCK, 60},
78 {1600, 1024, RES_1600X1024_60HZ_PIXCLOCK, 60},
79 {1680, 1050, RES_1680X1050_60HZ_PIXCLOCK, 60},
80 {1680, 1050, RES_1680X1050_75HZ_PIXCLOCK, 75},
81 {1792, 1344, RES_1792X1344_60HZ_PIXCLOCK, 60},
82 {1856, 1392, RES_1856X1392_60HZ_PIXCLOCK, 60},
83 {1920, 1200, RES_1920X1200_60HZ_PIXCLOCK, 60},
84 {1920, 1440, RES_1920X1440_60HZ_PIXCLOCK, 60},
85 {1920, 1440, RES_1920X1440_75HZ_PIXCLOCK, 75},
86 {2048, 1536, RES_2048X1536_60HZ_PIXCLOCK, 60}
87};
88
89struct io_reg CN400_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01},
90{VIASR, SR15, 0x02, 0x02},
91{VIASR, SR16, 0xBF, 0x08},
92{VIASR, SR17, 0xFF, 0x1F},
93{VIASR, SR18, 0xFF, 0x4E},
94{VIASR, SR1A, 0xFB, 0x08},
95{VIASR, SR1E, 0x0F, 0x01},
96{VIASR, SR2A, 0xFF, 0x00},
97{VIACR, CR0A, 0xFF, 0x1E}, /* Cursor Start */
98{VIACR, CR0B, 0xFF, 0x00}, /* Cursor End */
99{VIACR, CR0E, 0xFF, 0x00}, /* Cursor Location High */
100{VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */
101{VIACR, CR32, 0xFF, 0x00},
102{VIACR, CR33, 0xFF, 0x00},
103{VIACR, CR34, 0xFF, 0x00},
104{VIACR, CR35, 0xFF, 0x00},
105{VIACR, CR36, 0x08, 0x00},
106{VIACR, CR62, 0xFF, 0x00}, /* Secondary Display Starting Address */
107{VIACR, CR63, 0xFF, 0x00}, /* Secondary Display Starting Address */
108{VIACR, CR64, 0xFF, 0x00}, /* Secondary Display Starting Address */
109{VIACR, CR69, 0xFF, 0x00},
110{VIACR, CR6A, 0xFF, 0x40},
111{VIACR, CR6B, 0xFF, 0x00},
112{VIACR, CR6C, 0xFF, 0x00},
113{VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */
114{VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */
115{VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */
116{VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */
117{VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */
118{VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */
119{VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */
120{VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */
121{VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */
122{VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */
123{VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */
124{VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */
125{VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */
126{VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */
127{VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */
128{VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */
129{VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */
130{VIACR, CR8B, 0xFF, 0x69}, /* LCD Power Sequence Control 0 */
131{VIACR, CR8C, 0xFF, 0x57}, /* LCD Power Sequence Control 1 */
132{VIACR, CR8D, 0xFF, 0x00}, /* LCD Power Sequence Control 2 */
133{VIACR, CR8E, 0xFF, 0x7B}, /* LCD Power Sequence Control 3 */
134{VIACR, CR8F, 0xFF, 0x03}, /* LCD Power Sequence Control 4 */
135{VIACR, CR90, 0xFF, 0x30}, /* LCD Power Sequence Control 5 */
136{VIACR, CR91, 0xFF, 0xA0}, /* 24/12 bit LVDS Data off */
137{VIACR, CR96, 0xFF, 0x00},
138{VIACR, CR97, 0xFF, 0x00},
139{VIACR, CR99, 0xFF, 0x00},
140{VIACR, CR9B, 0xFF, 0x00}
141};
142
143/* Video Mode Table for VT3314 chipset*/
144/* Common Setting for Video Mode */
145struct io_reg CN700_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01},
146{VIASR, SR15, 0x02, 0x02},
147{VIASR, SR16, 0xBF, 0x08},
148{VIASR, SR17, 0xFF, 0x1F},
149{VIASR, SR18, 0xFF, 0x4E},
150{VIASR, SR1A, 0xFB, 0x82},
151{VIASR, SR1B, 0xFF, 0xF0},
152{VIASR, SR1F, 0xFF, 0x00},
153{VIASR, SR1E, 0xFF, 0x01},
154{VIASR, SR22, 0xFF, 0x1F},
155{VIASR, SR2A, 0x0F, 0x00},
156{VIASR, SR2E, 0xFF, 0xFF},
157{VIASR, SR3F, 0xFF, 0xFF},
158{VIASR, SR40, 0xF7, 0x00},
159{VIASR, CR30, 0xFF, 0x04},
160{VIACR, CR32, 0xFF, 0x00},
161{VIACR, CR33, 0x7F, 0x00},
162{VIACR, CR34, 0xFF, 0x00},
163{VIACR, CR35, 0xFF, 0x00},
164{VIACR, CR36, 0xFF, 0x31},
165{VIACR, CR41, 0xFF, 0x80},
166{VIACR, CR42, 0xFF, 0x00},
167{VIACR, CR55, 0x80, 0x00},
168{VIACR, CR5D, 0x80, 0x00}, /*Horizontal Retrace Start bit[11] should be 0*/
169{VIACR, CR62, 0xFF, 0x00}, /* Secondary Display Starting Address */
170{VIACR, CR63, 0xFF, 0x00}, /* Secondary Display Starting Address */
171{VIACR, CR64, 0xFF, 0x00}, /* Secondary Display Starting Address */
172{VIACR, CR68, 0xFF, 0x67}, /* Default FIFO For IGA2 */
173{VIACR, CR69, 0xFF, 0x00},
174{VIACR, CR6A, 0xFD, 0x40},
175{VIACR, CR6B, 0xFF, 0x00},
176{VIACR, CR6C, 0xFF, 0x00},
177{VIACR, CR77, 0xFF, 0x00}, /* LCD scaling Factor */
178{VIACR, CR78, 0xFF, 0x00}, /* LCD scaling Factor */
179{VIACR, CR79, 0xFF, 0x00}, /* LCD scaling Factor */
180{VIACR, CR9F, 0x03, 0x00}, /* LCD scaling Factor */
181{VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */
182{VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */
183{VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */
184{VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */
185{VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */
186{VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */
187{VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */
188{VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */
189{VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */
190{VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */
191{VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */
192{VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */
193{VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */
194{VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */
195{VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */
196{VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */
197{VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */
198{VIACR, CR8B, 0xFF, 0x5D}, /* LCD Power Sequence Control 0 */
199{VIACR, CR8C, 0xFF, 0x2B}, /* LCD Power Sequence Control 1 */
200{VIACR, CR8D, 0xFF, 0x6F}, /* LCD Power Sequence Control 2 */
201{VIACR, CR8E, 0xFF, 0x2B}, /* LCD Power Sequence Control 3 */
202{VIACR, CR8F, 0xFF, 0x01}, /* LCD Power Sequence Control 4 */
203{VIACR, CR90, 0xFF, 0x01}, /* LCD Power Sequence Control 5 */
204{VIACR, CR91, 0xFF, 0xA0}, /* 24/12 bit LVDS Data off */
205{VIACR, CR96, 0xFF, 0x00},
206{VIACR, CR97, 0xFF, 0x00},
207{VIACR, CR99, 0xFF, 0x00},
208{VIACR, CR9B, 0xFF, 0x00},
209{VIACR, CR9D, 0xFF, 0x80},
210{VIACR, CR9E, 0xFF, 0x80}
211};
212
213struct io_reg KM400_ModeXregs[] = {
214 {VIASR, SR10, 0xFF, 0x01}, /* Unlock Register */
215 {VIASR, SR16, 0xFF, 0x08}, /* Display FIFO threshold Control */
216 {VIASR, SR17, 0xFF, 0x1F}, /* Display FIFO Control */
217 {VIASR, SR18, 0xFF, 0x4E}, /* GFX PREQ threshold */
218 {VIASR, SR1A, 0xFF, 0x0a}, /* GFX PREQ threshold */
219 {VIASR, SR1F, 0xFF, 0x00}, /* Memory Control 0 */
220 {VIASR, SR1B, 0xFF, 0xF0}, /* Power Management Control 0 */
221 {VIASR, SR1E, 0xFF, 0x01}, /* Power Management Control */
222 {VIASR, SR20, 0xFF, 0x00}, /* Sequencer Arbiter Control 0 */
223 {VIASR, SR21, 0xFF, 0x00}, /* Sequencer Arbiter Control 1 */
224 {VIASR, SR22, 0xFF, 0x1F}, /* Display Arbiter Control 1 */
225 {VIASR, SR2A, 0xFF, 0x00}, /* Power Management Control 5 */
226 {VIASR, SR2D, 0xFF, 0xFF}, /* Power Management Control 1 */
227 {VIASR, SR2E, 0xFF, 0xFF}, /* Power Management Control 2 */
228 {VIACR, CR0A, 0xFF, 0x1E}, /* Cursor Start */
229 {VIACR, CR0B, 0xFF, 0x00}, /* Cursor End */
230 {VIACR, CR0E, 0xFF, 0x00}, /* Cursor Location High */
231 {VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */
232 {VIACR, CR33, 0xFF, 0x00},
233 {VIACR, CR55, 0x80, 0x00},
234 {VIACR, CR5D, 0x80, 0x00},
235 {VIACR, CR36, 0xFF, 0x01}, /* Power Mangement 3 */
236 {VIACR, CR62, 0xFF, 0x00}, /* Secondary Display Starting Address */
237 {VIACR, CR63, 0xFF, 0x00}, /* Secondary Display Starting Address */
238 {VIACR, CR64, 0xFF, 0x00}, /* Secondary Display Starting Address */
239 {VIACR, CR68, 0xFF, 0x67}, /* Default FIFO For IGA2 */
240 {VIACR, CR6A, 0x20, 0x20}, /* Extended FIFO On */
241 {VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */
242 {VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */
243 {VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */
244 {VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */
245 {VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */
246 {VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */
247 {VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */
248 {VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */
249 {VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */
250 {VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */
251 {VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */
252 {VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */
253 {VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */
254 {VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */
255 {VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */
256 {VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */
257 {VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */
258 {VIACR, CR8B, 0xFF, 0x2D}, /* LCD Power Sequence Control 0 */
259 {VIACR, CR8C, 0xFF, 0x2D}, /* LCD Power Sequence Control 1 */
260 {VIACR, CR8D, 0xFF, 0xC8}, /* LCD Power Sequence Control 2 */
261 {VIACR, CR8E, 0xFF, 0x36}, /* LCD Power Sequence Control 3 */
262 {VIACR, CR8F, 0xFF, 0x00}, /* LCD Power Sequence Control 4 */
263 {VIACR, CR90, 0xFF, 0x10}, /* LCD Power Sequence Control 5 */
264 {VIACR, CR91, 0xFF, 0xA0}, /* 24/12 bit LVDS Data off */
265 {VIACR, CR96, 0xFF, 0x03}, /* DVP0 ; DVP0 Clock Skew */
266 {VIACR, CR97, 0xFF, 0x03}, /* DFP high ; DFPH Clock Skew */
267 {VIACR, CR99, 0xFF, 0x03}, /* DFP low ; DFPL Clock Skew*/
268 {VIACR, CR9B, 0xFF, 0x07} /* DVI on DVP1 ; DVP1 Clock Skew*/
269};
270
271/* For VT3324: Common Setting for Video Mode */
272struct io_reg CX700_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01},
273{VIASR, SR15, 0x02, 0x02},
274{VIASR, SR16, 0xBF, 0x08},
275{VIASR, SR17, 0xFF, 0x1F},
276{VIASR, SR18, 0xFF, 0x4E},
277{VIASR, SR1A, 0xFB, 0x08},
278{VIASR, SR1B, 0xFF, 0xF0},
279{VIASR, SR1E, 0xFF, 0x01},
280{VIASR, SR2A, 0xFF, 0x00},
281{VIASR, SR2D, 0xFF, 0xFF}, /* VCK and LCK PLL power on. */
282{VIACR, CR0A, 0xFF, 0x1E}, /* Cursor Start */
283{VIACR, CR0B, 0xFF, 0x00}, /* Cursor End */
284{VIACR, CR0E, 0xFF, 0x00}, /* Cursor Location High */
285{VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */
286{VIACR, CR32, 0xFF, 0x00},
287{VIACR, CR33, 0xFF, 0x00},
288{VIACR, CR34, 0xFF, 0x00},
289{VIACR, CR35, 0xFF, 0x00},
290{VIACR, CR36, 0x08, 0x00},
291{VIACR, CR47, 0xC8, 0x00}, /* Clear VCK Plus. */
292{VIACR, CR62, 0xFF, 0x00}, /* Secondary Display Starting Address */
293{VIACR, CR63, 0xFF, 0x00}, /* Secondary Display Starting Address */
294{VIACR, CR64, 0xFF, 0x00}, /* Secondary Display Starting Address */
295{VIACR, CRA3, 0xFF, 0x00}, /* Secondary Display Starting Address */
296{VIACR, CR69, 0xFF, 0x00},
297{VIACR, CR6A, 0xFF, 0x40},
298{VIACR, CR6B, 0xFF, 0x00},
299{VIACR, CR6C, 0xFF, 0x00},
300{VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */
301{VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */
302{VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */
303{VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */
304{VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */
305{VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */
306{VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */
307{VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */
308{VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */
309{VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */
310{VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */
311{VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */
312{VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */
313{VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */
314{VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */
315{VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */
316{VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */
317{VIACR, CRD4, 0xFF, 0x81}, /* Second power sequence control */
318{VIACR, CR8B, 0xFF, 0x5D}, /* LCD Power Sequence Control 0 */
319{VIACR, CR8C, 0xFF, 0x2B}, /* LCD Power Sequence Control 1 */
320{VIACR, CR8D, 0xFF, 0x6F}, /* LCD Power Sequence Control 2 */
321{VIACR, CR8E, 0xFF, 0x2B}, /* LCD Power Sequence Control 3 */
322{VIACR, CR8F, 0xFF, 0x01}, /* LCD Power Sequence Control 4 */
323{VIACR, CR90, 0xFF, 0x01}, /* LCD Power Sequence Control 5 */
324{VIACR, CR91, 0xFF, 0x80}, /* 24/12 bit LVDS Data off */
325{VIACR, CR96, 0xFF, 0x00},
326{VIACR, CR97, 0xFF, 0x00},
327{VIACR, CR99, 0xFF, 0x00},
328{VIACR, CR9B, 0xFF, 0x00},
329{VIACR, CRD2, 0xFF, 0xFF} /* TMDS/LVDS control register. */
330};
331
332/* For VT3353: Common Setting for Video Mode */
333struct io_reg VX800_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01},
334{VIASR, SR15, 0x02, 0x02},
335{VIASR, SR16, 0xBF, 0x08},
336{VIASR, SR17, 0xFF, 0x1F},
337{VIASR, SR18, 0xFF, 0x4E},
338{VIASR, SR1A, 0xFB, 0x08},
339{VIASR, SR1B, 0xFF, 0xF0},
340{VIASR, SR1E, 0xFF, 0x01},
341{VIASR, SR2A, 0xFF, 0x00},
342{VIASR, SR2D, 0xFF, 0xFF}, /* VCK and LCK PLL power on. */
343{VIACR, CR0A, 0xFF, 0x1E}, /* Cursor Start */
344{VIACR, CR0B, 0xFF, 0x00}, /* Cursor End */
345{VIACR, CR0E, 0xFF, 0x00}, /* Cursor Location High */
346{VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */
347{VIACR, CR32, 0xFF, 0x00},
348{VIACR, CR33, 0xFF, 0x00},
349{VIACR, CR34, 0xFF, 0x00},
350{VIACR, CR35, 0xFF, 0x00},
351{VIACR, CR36, 0x08, 0x00},
352{VIACR, CR47, 0xC8, 0x00}, /* Clear VCK Plus. */
353{VIACR, CR62, 0xFF, 0x00}, /* Secondary Display Starting Address */
354{VIACR, CR63, 0xFF, 0x00}, /* Secondary Display Starting Address */
355{VIACR, CR64, 0xFF, 0x00}, /* Secondary Display Starting Address */
356{VIACR, CRA3, 0xFF, 0x00}, /* Secondary Display Starting Address */
357{VIACR, CR69, 0xFF, 0x00},
358{VIACR, CR6A, 0xFF, 0x40},
359{VIACR, CR6B, 0xFF, 0x00},
360{VIACR, CR6C, 0xFF, 0x00},
361{VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */
362{VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */
363{VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */
364{VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */
365{VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */
366{VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */
367{VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */
368{VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */
369{VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */
370{VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */
371{VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */
372{VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */
373{VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */
374{VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */
375{VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */
376{VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */
377{VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */
378{VIACR, CRD4, 0xFF, 0x81}, /* Second power sequence control */
379{VIACR, CR8B, 0xFF, 0x5D}, /* LCD Power Sequence Control 0 */
380{VIACR, CR8C, 0xFF, 0x2B}, /* LCD Power Sequence Control 1 */
381{VIACR, CR8D, 0xFF, 0x6F}, /* LCD Power Sequence Control 2 */
382{VIACR, CR8E, 0xFF, 0x2B}, /* LCD Power Sequence Control 3 */
383{VIACR, CR8F, 0xFF, 0x01}, /* LCD Power Sequence Control 4 */
384{VIACR, CR90, 0xFF, 0x01}, /* LCD Power Sequence Control 5 */
385{VIACR, CR91, 0xFF, 0x80}, /* 24/12 bit LVDS Data off */
386{VIACR, CR96, 0xFF, 0x00},
387{VIACR, CR97, 0xFF, 0x00},
388{VIACR, CR99, 0xFF, 0x00},
389{VIACR, CR9B, 0xFF, 0x00},
390{VIACR, CRD2, 0xFF, 0xFF} /* TMDS/LVDS control register. */
391};
392
393/* Video Mode Table */
394/* Common Setting for Video Mode */
395struct io_reg CLE266_ModeXregs[] = { {VIASR, SR1E, 0xF0, 0x00},
396{VIASR, SR2A, 0x0F, 0x00},
397{VIASR, SR15, 0x02, 0x02},
398{VIASR, SR16, 0xBF, 0x08},
399{VIASR, SR17, 0xFF, 0x1F},
400{VIASR, SR18, 0xFF, 0x4E},
401{VIASR, SR1A, 0xFB, 0x08},
402
403{VIACR, CR32, 0xFF, 0x00},
404{VIACR, CR34, 0xFF, 0x00},
405{VIACR, CR35, 0xFF, 0x00},
406{VIACR, CR36, 0x08, 0x00},
407{VIACR, CR6A, 0xFF, 0x80},
408{VIACR, CR6A, 0xFF, 0xC0},
409
410{VIACR, CR55, 0x80, 0x00},
411{VIACR, CR5D, 0x80, 0x00},
412
413{VIAGR, GR20, 0xFF, 0x00},
414{VIAGR, GR21, 0xFF, 0x00},
415{VIAGR, GR22, 0xFF, 0x00},
416 /* LCD Parameters */
417{VIACR, CR7A, 0xFF, 0x01}, /* LCD Parameter 1 */
418{VIACR, CR7B, 0xFF, 0x02}, /* LCD Parameter 2 */
419{VIACR, CR7C, 0xFF, 0x03}, /* LCD Parameter 3 */
420{VIACR, CR7D, 0xFF, 0x04}, /* LCD Parameter 4 */
421{VIACR, CR7E, 0xFF, 0x07}, /* LCD Parameter 5 */
422{VIACR, CR7F, 0xFF, 0x0A}, /* LCD Parameter 6 */
423{VIACR, CR80, 0xFF, 0x0D}, /* LCD Parameter 7 */
424{VIACR, CR81, 0xFF, 0x13}, /* LCD Parameter 8 */
425{VIACR, CR82, 0xFF, 0x16}, /* LCD Parameter 9 */
426{VIACR, CR83, 0xFF, 0x19}, /* LCD Parameter 10 */
427{VIACR, CR84, 0xFF, 0x1C}, /* LCD Parameter 11 */
428{VIACR, CR85, 0xFF, 0x1D}, /* LCD Parameter 12 */
429{VIACR, CR86, 0xFF, 0x1E}, /* LCD Parameter 13 */
430{VIACR, CR87, 0xFF, 0x1F}, /* LCD Parameter 14 */
431
432};
433
434/* Mode:1024X768 */
435struct io_reg PM1024x768[] = { {VIASR, 0x16, 0xBF, 0x0C},
436{VIASR, 0x18, 0xFF, 0x4C}
437};
438
439struct patch_table res_patch_table[] = {
440 {VIA_RES_1024X768, ARRAY_SIZE(PM1024x768), PM1024x768}
441};
442
443/* struct VPITTable {
444 unsigned char Misc;
445 unsigned char SR[StdSR];
446 unsigned char CR[StdCR];
447 unsigned char GR[StdGR];
448 unsigned char AR[StdAR];
449 };*/
450
451struct VPITTable VPIT = {
452 /* Msic */
453 0xC7,
454 /* Sequencer */
455 {0x01, 0x0F, 0x00, 0x0E},
456 /* Graphic Controller */
457 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF},
458 /* Attribute Controller */
459 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
460 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
461 0x01, 0x00, 0x0F, 0x00}
462};
463
464/********************/
465/* Mode Table */
466/********************/
467
468/* 480x640 */
469struct crt_mode_table CRTM480x640[] = {
470 /* r_rate, vclk, hsp, vsp */
471 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
472 {REFRESH_60, CLK_25_175M, M480X640_R60_HSP, M480X640_R60_VSP,
473 {624, 480, 480, 144, 504, 48, 663, 640, 640, 23, 641, 3} } /* GTF*/
474};
475
476/* 640x480*/
477struct crt_mode_table CRTM640x480[] = {
478 /*r_rate,vclk,hsp,vsp */
479 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
480 {REFRESH_60, CLK_25_175M, M640X480_R60_HSP, M640X480_R60_VSP,
481 {800, 640, 648, 144, 656, 96, 525, 480, 480, 45, 490, 2} },
482 {REFRESH_75, CLK_31_500M, M640X480_R75_HSP, M640X480_R75_VSP,
483 {840, 640, 640, 200, 656, 64, 500, 480, 480, 20, 481, 3} },
484 {REFRESH_85, CLK_36_000M, M640X480_R85_HSP, M640X480_R85_VSP,
485 {832, 640, 640, 192, 696, 56, 509, 480, 480, 29, 481, 3} },
486 {REFRESH_100, CLK_43_163M, M640X480_R100_HSP, M640X480_R100_VSP,
487 {848, 640, 640, 208, 680, 64, 509, 480, 480, 29, 481, 3} }, /*GTF*/
488 {REFRESH_120, CLK_52_406M, M640X480_R120_HSP,
489 M640X480_R120_VSP,
490 {848, 640, 640, 208, 680, 64, 515, 480, 480, 35, 481,
491 3} } /*GTF*/
492};
493
494/*720x480 (GTF)*/
495struct crt_mode_table CRTM720x480[] = {
496 /*r_rate,vclk,hsp,vsp */
497 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
498 {REFRESH_60, CLK_26_880M, M720X480_R60_HSP, M720X480_R60_VSP,
499 {896, 720, 720, 176, 736, 72, 497, 480, 480, 17, 481, 3} }
500
501};
502
503/*720x576 (GTF)*/
504struct crt_mode_table CRTM720x576[] = {
505 /*r_rate,vclk,hsp,vsp */
506 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
507 {REFRESH_60, CLK_32_668M, M720X576_R60_HSP, M720X576_R60_VSP,
508 {912, 720, 720, 192, 744, 72, 597, 576, 576, 21, 577, 3} }
509};
510
511/* 800x480 (CVT) */
512struct crt_mode_table CRTM800x480[] = {
513 /* r_rate, vclk, hsp, vsp */
514 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
515 {REFRESH_60, CLK_29_581M, M800X480_R60_HSP, M800X480_R60_VSP,
516 {992, 800, 800, 192, 824, 72, 500, 480, 480, 20, 483, 7} }
517};
518
519/* 800x600*/
520struct crt_mode_table CRTM800x600[] = {
521 /*r_rate,vclk,hsp,vsp */
522 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
523 {REFRESH_60, CLK_40_000M, M800X600_R60_HSP, M800X600_R60_VSP,
524 {1056, 800, 800, 256, 840, 128, 628, 600, 600, 28, 601, 4} },
525 {REFRESH_75, CLK_49_500M, M800X600_R75_HSP, M800X600_R75_VSP,
526 {1056, 800, 800, 256, 816, 80, 625, 600, 600, 25, 601, 3} },
527 {REFRESH_85, CLK_56_250M, M800X600_R85_HSP, M800X600_R85_VSP,
528 {1048, 800, 800, 248, 832, 64, 631, 600, 600, 31, 601, 3} },
529 {REFRESH_100, CLK_68_179M, M800X600_R100_HSP, M800X600_R100_VSP,
530 {1072, 800, 800, 272, 848, 88, 636, 600, 600, 36, 601, 3} },
531 {REFRESH_120, CLK_83_950M, M800X600_R120_HSP,
532 M800X600_R120_VSP,
533 {1088, 800, 800, 288, 856, 88, 643, 600, 600, 43, 601,
534 3} }
535};
536
537/* 848x480 (CVT) */
538struct crt_mode_table CRTM848x480[] = {
539 /* r_rate, vclk, hsp, vsp */
540 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
541 {REFRESH_60, CLK_31_500M, M848X480_R60_HSP, M848X480_R60_VSP,
542 {1056, 848, 848, 208, 872, 80, 500, 480, 480, 20, 483, 5} }
543};
544
545/*856x480 (GTF) convert to 852x480*/
546struct crt_mode_table CRTM852x480[] = {
547 /*r_rate,vclk,hsp,vsp */
548 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
549 {REFRESH_60, CLK_31_728M, M852X480_R60_HSP, M852X480_R60_VSP,
550 {1064, 856, 856, 208, 872, 88, 497, 480, 480, 17, 481, 3} }
551};
552
553/*1024x512 (GTF)*/
554struct crt_mode_table CRTM1024x512[] = {
555 /*r_rate,vclk,hsp,vsp */
556 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
557 {REFRESH_60, CLK_41_291M, M1024X512_R60_HSP, M1024X512_R60_VSP,
558 {1296, 1024, 1024, 272, 1056, 104, 531, 512, 512, 19, 513, 3} }
559
560};
561
562/* 1024x600*/
563struct crt_mode_table CRTM1024x600[] = {
564 /*r_rate,vclk,hsp,vsp */
565 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
566 {REFRESH_60, CLK_48_875M, M1024X600_R60_HSP, M1024X600_R60_VSP,
567 {1312, 1024, 1024, 288, 1064, 104, 622, 600, 600, 22, 601, 3} },
568};
569
570/* 1024x768*/
571struct crt_mode_table CRTM1024x768[] = {
572 /*r_rate,vclk,hsp,vsp */
573 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
574 {REFRESH_60, CLK_65_000M, M1024X768_R60_HSP, M1024X768_R60_VSP,
575 {1344, 1024, 1024, 320, 1048, 136, 806, 768, 768, 38, 771, 6} },
576 {REFRESH_75, CLK_78_750M, M1024X768_R75_HSP, M1024X768_R75_VSP,
577 {1312, 1024, 1024, 288, 1040, 96, 800, 768, 768, 32, 769, 3} },
578 {REFRESH_85, CLK_94_500M, M1024X768_R85_HSP, M1024X768_R85_VSP,
579 {1376, 1024, 1024, 352, 1072, 96, 808, 768, 768, 40, 769, 3} },
580 {REFRESH_100, CLK_113_309M, M1024X768_R100_HSP, M1024X768_R100_VSP,
581 {1392, 1024, 1024, 368, 1096, 112, 814, 768, 768, 46, 769, 3} }
582};
583
584/* 1152x864*/
585struct crt_mode_table CRTM1152x864[] = {
586 /*r_rate,vclk,hsp,vsp */
587 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
588 {REFRESH_75, CLK_108_000M, M1152X864_R75_HSP, M1152X864_R75_VSP,
589 {1600, 1152, 1152, 448, 1216, 128, 900, 864, 864, 36, 865, 3} }
590
591};
592
593/* 1280x720 (HDMI 720P)*/
594struct crt_mode_table CRTM1280x720[] = {
595 /*r_rate,vclk,hsp,vsp */
596 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
597 {REFRESH_60, CLK_74_481M, M1280X720_R60_HSP, M1280X720_R60_VSP,
598 {1648, 1280, 1280, 368, 1392, 40, 750, 720, 720, 30, 725, 5} },
599 {REFRESH_50, CLK_60_466M, M1280X720_R50_HSP, M1280X720_R50_VSP,
600 {1632, 1280, 1280, 352, 1328, 128, 741, 720, 720, 21, 721, 3} }
601};
602
603/*1280x768 (GTF)*/
604struct crt_mode_table CRTM1280x768[] = {
605 /*r_rate,vclk,hsp,vsp */
606 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
607 {REFRESH_60, CLK_80_136M, M1280X768_R60_HSP, M1280X768_R60_VSP,
608 {1680, 1280, 1280, 400, 1344, 136, 795, 768, 768, 27, 769, 3} },
609 {REFRESH_50, CLK_65_178M, M1280X768_R50_HSP, M1280X768_R50_VSP,
610 {1648, 1280, 1280, 368, 1336, 128, 791, 768, 768, 23, 769, 3} }
611};
612
613/* 1280x800 (CVT) */
614struct crt_mode_table CRTM1280x800[] = {
615 /* r_rate, vclk, hsp, vsp */
616 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
617 {REFRESH_60, CLK_83_375M, M1280X800_R60_HSP, M1280X800_R60_VSP,
618 {1680, 1280, 1280, 400, 1352, 128, 831, 800, 800, 31, 803, 6} }
619};
620
621/*1280x960*/
622struct crt_mode_table CRTM1280x960[] = {
623 /*r_rate,vclk,hsp,vsp */
624 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
625 {REFRESH_60, CLK_108_000M, M1280X960_R60_HSP, M1280X960_R60_VSP,
626 {1800, 1280, 1280, 520, 1376, 112, 1000, 960, 960, 40, 961, 3} }
627};
628
629/* 1280x1024*/
630struct crt_mode_table CRTM1280x1024[] = {
631 /*r_rate,vclk,,hsp,vsp */
632 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
633 {REFRESH_60, CLK_108_000M, M1280X1024_R60_HSP, M1280X1024_R60_VSP,
634 {1688, 1280, 1280, 408, 1328, 112, 1066, 1024, 1024, 42, 1025,
635 3} },
636 {REFRESH_75, CLK_135_000M, M1280X1024_R75_HSP, M1280X1024_R75_VSP,
637 {1688, 1280, 1280, 408, 1296, 144, 1066, 1024, 1024, 42, 1025,
638 3} },
639 {REFRESH_85, CLK_157_500M, M1280X1024_R85_HSP, M1280X1024_R85_VSP,
640 {1728, 1280, 1280, 448, 1344, 160, 1072, 1024, 1024, 48, 1025, 3} }
641};
642
643/* 1368x768 (GTF) */
644struct crt_mode_table CRTM1368x768[] = {
645 /* r_rate, vclk, hsp, vsp */
646 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
647 {REFRESH_60, CLK_85_860M, M1368X768_R60_HSP, M1368X768_R60_VSP,
648 {1800, 1368, 1368, 432, 1440, 144, 795, 768, 768, 27, 769, 3} }
649};
650
651/*1440x1050 (GTF)*/
652struct crt_mode_table CRTM1440x1050[] = {
653 /*r_rate,vclk,hsp,vsp */
654 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
655 {REFRESH_60, CLK_125_104M, M1440X1050_R60_HSP, M1440X1050_R60_VSP,
656 {1936, 1440, 1440, 496, 1536, 152, 1077, 1040, 1040, 37, 1041, 3} }
657};
658
659/* 1600x1200*/
660struct crt_mode_table CRTM1600x1200[] = {
661 /*r_rate,vclk,hsp,vsp */
662 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
663 {REFRESH_60, CLK_162_000M, M1600X1200_R60_HSP, M1600X1200_R60_VSP,
664 {2160, 1600, 1600, 560, 1664, 192, 1250, 1200, 1200, 50, 1201,
665 3} },
666 {REFRESH_75, CLK_202_500M, M1600X1200_R75_HSP, M1600X1200_R75_VSP,
667 {2160, 1600, 1600, 560, 1664, 192, 1250, 1200, 1200, 50, 1201, 3} }
668
669};
670
671/* 1680x1050 (CVT) */
672struct crt_mode_table CRTM1680x1050[] = {
673 /* r_rate, vclk, hsp, vsp */
674 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
675 {REFRESH_60, CLK_146_760M, M1680x1050_R60_HSP, M1680x1050_R60_VSP,
676 {2240, 1680, 1680, 560, 1784, 176, 1089, 1050, 1050, 39, 1053,
677 6} },
678 {REFRESH_75, CLK_187_000M, M1680x1050_R75_HSP, M1680x1050_R75_VSP,
679 {2272, 1680, 1680, 592, 1800, 176, 1099, 1050, 1050, 49, 1053, 6} }
680};
681
682/* 1680x1050 (CVT Reduce Blanking) */
683struct crt_mode_table CRTM1680x1050_RB[] = {
684 /* r_rate, vclk, hsp, vsp */
685 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
686 {REFRESH_60, CLK_119_000M, M1680x1050_RB_R60_HSP,
687 M1680x1050_RB_R60_VSP,
688 {1840, 1680, 1680, 160, 1728, 32, 1080, 1050, 1050, 30, 1053, 6} }
689};
690
691/* 1920x1080 (CVT)*/
692struct crt_mode_table CRTM1920x1080[] = {
693 /*r_rate,vclk,hsp,vsp */
694 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
695 {REFRESH_60, CLK_172_798M, M1920X1080_R60_HSP, M1920X1080_R60_VSP,
696 {2576, 1920, 1920, 656, 2048, 200, 1120, 1080, 1080, 40, 1083, 5} }
697};
698
699/* 1920x1080 (CVT with Reduce Blanking) */
700struct crt_mode_table CRTM1920x1080_RB[] = {
701 /* r_rate, vclk, hsp, vsp */
702 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
703 {REFRESH_60, CLK_138_400M, M1920X1080_RB_R60_HSP,
704 M1920X1080_RB_R60_VSP,
705 {2080, 1920, 1920, 160, 1968, 32, 1111, 1080, 1080, 31, 1083, 5} }
706};
707
708/* 1920x1440*/
709struct crt_mode_table CRTM1920x1440[] = {
710 /*r_rate,vclk,hsp,vsp */
711 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
712 {REFRESH_60, CLK_234_000M, M1920X1440_R60_HSP, M1920X1440_R60_VSP,
713 {2600, 1920, 1920, 680, 2048, 208, 1500, 1440, 1440, 60, 1441,
714 3} },
715 {REFRESH_75, CLK_297_500M, M1920X1440_R75_HSP, M1920X1440_R75_VSP,
716 {2640, 1920, 1920, 720, 2064, 224, 1500, 1440, 1440, 60, 1441, 3} }
717};
718
719/* 1400x1050 (CVT) */
720struct crt_mode_table CRTM1400x1050[] = {
721 /* r_rate, vclk, hsp, vsp */
722 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
723 {REFRESH_60, CLK_121_750M, M1400X1050_R60_HSP, M1400X1050_R60_VSP,
724 {1864, 1400, 1400, 464, 1488, 144, 1089, 1050, 1050, 39, 1053,
725 4} },
726 {REFRESH_75, CLK_156_000M, M1400X1050_R75_HSP, M1400X1050_R75_VSP,
727 {1896, 1400, 1400, 496, 1504, 144, 1099, 1050, 1050, 49, 1053, 4} }
728};
729
730/* 1400x1050 (CVT Reduce Blanking) */
731struct crt_mode_table CRTM1400x1050_RB[] = {
732 /* r_rate, vclk, hsp, vsp */
733 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
734 {REFRESH_60, CLK_101_000M, M1400X1050_RB_R60_HSP,
735 M1400X1050_RB_R60_VSP,
736 {1560, 1400, 1400, 160, 1448, 32, 1080, 1050, 1050, 30, 1053, 4} }
737};
738
739/* 960x600 (CVT) */
740struct crt_mode_table CRTM960x600[] = {
741 /* r_rate, vclk, hsp, vsp */
742 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
743 {REFRESH_60, CLK_45_250M, M960X600_R60_HSP, M960X600_R60_VSP,
744 {1216, 960, 960, 256, 992, 96, 624, 600, 600, 24, 603, 6} }
745};
746
747/* 1000x600 (GTF) */
748struct crt_mode_table CRTM1000x600[] = {
749 /* r_rate, vclk, hsp, vsp */
750 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
751 {REFRESH_60, CLK_48_000M, M1000X600_R60_HSP, M1000X600_R60_VSP,
752 {1288, 1000, 1000, 288, 1040, 104, 622, 600, 600, 22, 601, 3} }
753};
754
755/* 1024x576 (GTF) */
756struct crt_mode_table CRTM1024x576[] = {
757 /* r_rate, vclk, hsp, vsp */
758 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
759 {REFRESH_60, CLK_46_996M, M1024X576_R60_HSP, M1024X576_R60_VSP,
760 {1312, 1024, 1024, 288, 1064, 104, 597, 576, 576, 21, 577, 3} }
761};
762
763/* 1088x612 (CVT) */
764struct crt_mode_table CRTM1088x612[] = {
765 /* r_rate, vclk, hsp, vsp */
766 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
767 {REFRESH_60, CLK_52_977M, M1088X612_R60_HSP, M1088X612_R60_VSP,
768 {1392, 1088, 1088, 304, 1136, 104, 636, 612, 612, 24, 615, 5} }
769};
770
771/* 1152x720 (CVT) */
772struct crt_mode_table CRTM1152x720[] = {
773 /* r_rate, vclk, hsp, vsp */
774 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
775 {REFRESH_60, CLK_66_750M, M1152X720_R60_HSP, M1152X720_R60_VSP,
776 {1488, 1152, 1152, 336, 1208, 112, 748, 720, 720, 28, 723, 6} }
777};
778
779/* 1200x720 (GTF) */
780struct crt_mode_table CRTM1200x720[] = {
781 /* r_rate, vclk, hsp, vsp */
782 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
783 {REFRESH_60, CLK_70_159M, M1200X720_R60_HSP, M1200X720_R60_VSP,
784 {1568, 1200, 1200, 368, 1256, 128, 746, 720, 720, 26, 721, 3} }
785};
786
787/* 1280x600 (GTF) */
788struct crt_mode_table CRTM1280x600[] = {
789 /* r_rate, vclk, hsp, vsp */
790 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
791 {REFRESH_60, CLK_61_500M, M1280x600_R60_HSP, M1280x600_R60_VSP,
792 {1648, 1280, 1280, 368, 1336, 128, 622, 600, 600, 22, 601, 3} }
793};
794
795/* 1360x768 (CVT) */
796struct crt_mode_table CRTM1360x768[] = {
797 /* r_rate, vclk, hsp, vsp */
798 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
799 {REFRESH_60, CLK_84_750M, M1360X768_R60_HSP, M1360X768_R60_VSP,
800 {1776, 1360, 1360, 416, 1432, 136, 798, 768, 768, 30, 771, 5} }
801};
802
803/* 1360x768 (CVT Reduce Blanking) */
804struct crt_mode_table CRTM1360x768_RB[] = {
805 /* r_rate, vclk, hsp, vsp */
806 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
807 {REFRESH_60, CLK_72_000M, M1360X768_RB_R60_HSP,
808 M1360X768_RB_R60_VSP,
809 {1520, 1360, 1360, 160, 1408, 32, 790, 768, 768, 22, 771, 5} }
810};
811
812/* 1366x768 (GTF) */
813struct crt_mode_table CRTM1366x768[] = {
814 /* r_rate, vclk, hsp, vsp */
815 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
816 {REFRESH_60, CLK_85_860M, M1368X768_R60_HSP, M1368X768_R60_VSP,
817 {1800, 1368, 1368, 432, 1440, 144, 795, 768, 768, 27, 769, 3} },
818 {REFRESH_50, CLK_69_924M, M1368X768_R50_HSP, M1368X768_R50_VSP,
819 {1768, 1368, 1368, 400, 1424, 144, 791, 768, 768, 23, 769, 3} }
820};
821
822/* 1440x900 (CVT) */
823struct crt_mode_table CRTM1440x900[] = {
824 /* r_rate, vclk, hsp, vsp */
825 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
826 {REFRESH_60, CLK_106_500M, M1440X900_R60_HSP, M1440X900_R60_VSP,
827 {1904, 1440, 1440, 464, 1520, 152, 934, 900, 900, 34, 903, 6} },
828 {REFRESH_75, CLK_136_700M, M1440X900_R75_HSP, M1440X900_R75_VSP,
829 {1936, 1440, 1440, 496, 1536, 152, 942, 900, 900, 42, 903, 6} }
830};
831
832/* 1440x900 (CVT Reduce Blanking) */
833struct crt_mode_table CRTM1440x900_RB[] = {
834 /* r_rate, vclk, hsp, vsp */
835 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
836 {REFRESH_60, CLK_88_750M, M1440X900_RB_R60_HSP,
837 M1440X900_RB_R60_VSP,
838 {1600, 1440, 1440, 160, 1488, 32, 926, 900, 900, 26, 903, 6} }
839};
840
841/* 1600x900 (CVT) */
842struct crt_mode_table CRTM1600x900[] = {
843 /* r_rate, vclk, hsp, vsp */
844 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
845 {REFRESH_60, CLK_118_840M, M1600X900_R60_HSP, M1600X900_R60_VSP,
846 {2112, 1600, 1600, 512, 1688, 168, 934, 900, 900, 34, 903, 5} }
847};
848
849/* 1600x900 (CVT Reduce Blanking) */
850struct crt_mode_table CRTM1600x900_RB[] = {
851 /* r_rate, vclk, hsp, vsp */
852 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
853 {REFRESH_60, CLK_97_750M, M1600X900_RB_R60_HSP,
854 M1600X900_RB_R60_VSP,
855 {1760, 1600, 1600, 160, 1648, 32, 926, 900, 900, 26, 903, 5} }
856};
857
858/* 1600x1024 (GTF) */
859struct crt_mode_table CRTM1600x1024[] = {
860 /* r_rate, vclk, hsp, vsp */
861 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
862 {REFRESH_60, CLK_136_700M, M1600X1024_R60_HSP, M1600X1024_R60_VSP,
863 {2144, 1600, 1600, 544, 1704, 168, 1060, 1024, 1024, 36, 1025, 3} }
864};
865
866/* 1792x1344 (DMT) */
867struct crt_mode_table CRTM1792x1344[] = {
868 /* r_rate, vclk, hsp, vsp */
869 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
870 {REFRESH_60, CLK_204_000M, M1792x1344_R60_HSP, M1792x1344_R60_VSP,
871 {2448, 1792, 1792, 656, 1920, 200, 1394, 1344, 1344, 50, 1345, 3} }
872};
873
874/* 1856x1392 (DMT) */
875struct crt_mode_table CRTM1856x1392[] = {
876 /* r_rate, vclk, hsp, vsp */
877 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
878 {REFRESH_60, CLK_218_500M, M1856x1392_R60_HSP, M1856x1392_R60_VSP,
879 {2528, 1856, 1856, 672, 1952, 224, 1439, 1392, 1392, 47, 1393, 3} }
880};
881
882/* 1920x1200 (CVT) */
883struct crt_mode_table CRTM1920x1200[] = {
884 /* r_rate, vclk, hsp, vsp */
885 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
886 {REFRESH_60, CLK_193_295M, M1920X1200_R60_HSP, M1920X1200_R60_VSP,
887 {2592, 1920, 1920, 672, 2056, 200, 1245, 1200, 1200, 45, 1203, 6} }
888};
889
890/* 1920x1200 (CVT with Reduce Blanking) */
891struct crt_mode_table CRTM1920x1200_RB[] = {
892 /* r_rate, vclk, hsp, vsp */
893 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
894 {REFRESH_60, CLK_153_920M, M1920X1200_RB_R60_HSP,
895 M1920X1200_RB_R60_VSP,
896 {2080, 1920, 1920, 160, 1968, 32, 1235, 1200, 1200, 35, 1203, 6} }
897};
898
899/* 2048x1536 (CVT) */
900struct crt_mode_table CRTM2048x1536[] = {
901 /* r_rate, vclk, hsp, vsp */
902 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
903 {REFRESH_60, CLK_267_250M, M2048x1536_R60_HSP, M2048x1536_R60_VSP,
904 {2800, 2048, 2048, 752, 2200, 224, 1592, 1536, 1536, 56, 1539, 4} }
905};
906
907/* Video Mode Table */
908/* struct VideoModeTable {*/
909/* int ModeIndex;*/
910/* struct crt_mode_table *crtc;*/
911/* int mode_array;*/
912/* };*/
913struct VideoModeTable CLE266Modes[] = {
914 /* Display : 480x640 (GTF) */
915 {VIA_RES_480X640, CRTM480x640, ARRAY_SIZE(CRTM480x640)},
916
917 /* Display : 640x480 */
918 {VIA_RES_640X480, CRTM640x480, ARRAY_SIZE(CRTM640x480)},
919
920 /* Display : 720x480 (GTF) */
921 {VIA_RES_720X480, CRTM720x480, ARRAY_SIZE(CRTM720x480)},
922
923 /* Display : 720x576 (GTF) */
924 {VIA_RES_720X576, CRTM720x576, ARRAY_SIZE(CRTM720x576)},
925
926 /* Display : 800x600 */
927 {VIA_RES_800X600, CRTM800x600, ARRAY_SIZE(CRTM800x600)},
928
929 /* Display : 800x480 (CVT) */
930 {VIA_RES_800X480, CRTM800x480, ARRAY_SIZE(CRTM800x480)},
931
932 /* Display : 848x480 (CVT) */
933 {VIA_RES_848X480, CRTM848x480, ARRAY_SIZE(CRTM848x480)},
934
935 /* Display : 852x480 (GTF) */
936 {VIA_RES_856X480, CRTM852x480, ARRAY_SIZE(CRTM852x480)},
937
938 /* Display : 1024x512 (GTF) */
939 {VIA_RES_1024X512, CRTM1024x512, ARRAY_SIZE(CRTM1024x512)},
940
941 /* Display : 1024x600 */
942 {VIA_RES_1024X600, CRTM1024x600, ARRAY_SIZE(CRTM1024x600)},
943
944 /* Display : 1024x576 (GTF) */
945 /*{ VIA_RES_1024X576, CRTM1024x576, ARRAY_SIZE(CRTM1024x576)}, */
946
947 /* Display : 1024x768 */
948 {VIA_RES_1024X768, CRTM1024x768, ARRAY_SIZE(CRTM1024x768)},
949
950 /* Display : 1152x864 */
951 {VIA_RES_1152X864, CRTM1152x864, ARRAY_SIZE(CRTM1152x864)},
952
953 /* Display : 1280x768 (GTF) */
954 {VIA_RES_1280X768, CRTM1280x768, ARRAY_SIZE(CRTM1280x768)},
955
956 /* Display : 960x600 (CVT) */
957 {VIA_RES_960X600, CRTM960x600, ARRAY_SIZE(CRTM960x600)},
958
959 /* Display : 1000x600 (GTF) */
960 {VIA_RES_1000X600, CRTM1000x600, ARRAY_SIZE(CRTM1000x600)},
961
962 /* Display : 1024x576 (GTF) */
963 {VIA_RES_1024X576, CRTM1024x576, ARRAY_SIZE(CRTM1024x576)},
964
965 /* Display : 1088x612 (GTF) */
966 {VIA_RES_1088X612, CRTM1088x612, ARRAY_SIZE(CRTM1088x612)},
967
968 /* Display : 1152x720 (CVT) */
969 {VIA_RES_1152X720, CRTM1152x720, ARRAY_SIZE(CRTM1152x720)},
970
971 /* Display : 1200x720 (GTF) */
972 {VIA_RES_1200X720, CRTM1200x720, ARRAY_SIZE(CRTM1200x720)},
973
974 /* Display : 1280x600 (GTF) */
975 {VIA_RES_1280X600, CRTM1280x600, ARRAY_SIZE(CRTM1280x600)},
976
977 /* Display : 1280x800 (CVT) */
978 {VIA_RES_1280X800, CRTM1280x800, ARRAY_SIZE(CRTM1280x800)},
979
980 /* Display : 1280x800 (GTF) */
981 /*{ M1280x800, CRTM1280x800, ARRAY_SIZE(CRTM1280x800)}, */
982
983 /* Display : 1280x960 */
984 {VIA_RES_1280X960, CRTM1280x960, ARRAY_SIZE(CRTM1280x960)},
985
986 /* Display : 1280x1024 */
987 {VIA_RES_1280X1024, CRTM1280x1024, ARRAY_SIZE(CRTM1280x1024)},
988
989 /* Display : 1360x768 (CVT) */
990 {VIA_RES_1360X768, CRTM1360x768, ARRAY_SIZE(CRTM1360x768)},
991
992 /* Display : 1360x768 (CVT Reduce Blanking) */
993 {VIA_RES_1360X768_RB, CRTM1360x768_RB,
994 ARRAY_SIZE(CRTM1360x768_RB)},
995
996 /* Display : 1366x768 */
997 {VIA_RES_1366X768, CRTM1366x768, ARRAY_SIZE(CRTM1366x768)},
998
999 /* Display : 1368x768 (GTF) */
1000 /*{ M1368x768,CRTM1368x768,ARRAY_SIZE(CRTM1368x768)}, */
1001 /* Display : 1368x768 (GTF) */
1002 {VIA_RES_1368X768, CRTM1368x768, ARRAY_SIZE(CRTM1368x768)},
1003
1004 /* Display : 1440x900 (CVT) */
1005 {VIA_RES_1440X900, CRTM1440x900, ARRAY_SIZE(CRTM1440x900)},
1006
1007 /* Display : 1440x900 (CVT Reduce Blanking) */
1008 {VIA_RES_1440X900_RB, CRTM1440x900_RB,
1009 ARRAY_SIZE(CRTM1440x900_RB)},
1010
1011 /* Display : 1440x1050 (GTF) */
1012 {VIA_RES_1440X1050, CRTM1440x1050, ARRAY_SIZE(CRTM1440x1050)},
1013
1014 /* Display : 1400x1050 (CVT Reduce Blanking) */
1015 {VIA_RES_1400X1050_RB, CRTM1400x1050_RB,
1016 ARRAY_SIZE(CRTM1400x1050_RB)},
1017
1018 /* Display : 1600x900 (CVT) */
1019 {VIA_RES_1600X900, CRTM1600x900, ARRAY_SIZE(CRTM1600x900)},
1020
1021 /* Display : 1600x900 (CVT Reduce Blanking) */
1022 {VIA_RES_1600X900_RB, CRTM1600x900_RB,
1023 ARRAY_SIZE(CRTM1600x900_RB)},
1024
1025 /* Display : 1600x1024 (GTF) */
1026 {VIA_RES_1600X1024, CRTM1600x1024, ARRAY_SIZE(CRTM1600x1024)},
1027
1028 /* Display : 1600x1200 */
1029 {VIA_RES_1600X1200, CRTM1600x1200, ARRAY_SIZE(CRTM1600x1200)},
1030
1031 /* Display : 1680x1050 (CVT) */
1032 {VIA_RES_1680X1050, CRTM1680x1050, ARRAY_SIZE(CRTM1680x1050)},
1033
1034 /* Display : 1680x1050 (CVT Reduce Blanking) */
1035 {VIA_RES_1680X1050_RB, CRTM1680x1050_RB,
1036 ARRAY_SIZE(CRTM1680x1050_RB)},
1037
1038 /* Display : 1792x1344 (DMT) */
1039 {VIA_RES_1792X1344, CRTM1792x1344, ARRAY_SIZE(CRTM1792x1344)},
1040
1041 /* Display : 1856x1392 (DMT) */
1042 {VIA_RES_1856X1392, CRTM1856x1392, ARRAY_SIZE(CRTM1856x1392)},
1043
1044 /* Display : 1920x1440 */
1045 {VIA_RES_1920X1440, CRTM1920x1440, ARRAY_SIZE(CRTM1920x1440)},
1046
1047 /* Display : 2048x1536 */
1048 {VIA_RES_2048X1536, CRTM2048x1536, ARRAY_SIZE(CRTM2048x1536)},
1049
1050 /* Display : 1280x720 */
1051 {VIA_RES_1280X720, CRTM1280x720, ARRAY_SIZE(CRTM1280x720)},
1052
1053 /* Display : 1920x1080 (CVT) */
1054 {VIA_RES_1920X1080, CRTM1920x1080, ARRAY_SIZE(CRTM1920x1080)},
1055
1056 /* Display : 1920x1080 (CVT Reduce Blanking) */
1057 {VIA_RES_1920X1080_RB, CRTM1920x1080_RB,
1058 ARRAY_SIZE(CRTM1920x1080_RB)},
1059
1060 /* Display : 1920x1200 (CVT) */
1061 {VIA_RES_1920X1200, CRTM1920x1200, ARRAY_SIZE(CRTM1920x1200)},
1062
1063 /* Display : 1920x1200 (CVT Reduce Blanking) */
1064 {VIA_RES_1920X1200_RB, CRTM1920x1200_RB,
1065 ARRAY_SIZE(CRTM1920x1200_RB)},
1066
1067 /* Display : 1400x1050 (CVT) */
1068 {VIA_RES_1400X1050, CRTM1400x1050, ARRAY_SIZE(CRTM1400x1050)}
1069};
1070struct crt_mode_table CEAM1280x720[] = {
1071 {REFRESH_60, CLK_74_270M, M1280X720_CEA_R60_HSP,
1072 M1280X720_CEA_R60_VSP,
1073 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
1074 {1650, 1280, 1280, 370, 1390, 40, 750, 720, 720, 30, 725, 5} }
1075};
1076struct crt_mode_table CEAM1920x1080[] = {
1077 {REFRESH_60, CLK_148_500M, M1920X1080_CEA_R60_HSP,
1078 M1920X1080_CEA_R60_VSP,
1079 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
1080 {2200, 1920, 1920, 300, 2008, 44, 1125, 1080, 1080, 45, 1084, 5} }
1081};
1082struct VideoModeTable CEA_HDMI_Modes[] = {
1083 /* Display : 1280x720 */
1084 {VIA_RES_1280X720, CEAM1280x720, ARRAY_SIZE(CEAM1280x720)},
1085 {VIA_RES_1920X1080, CEAM1920x1080, ARRAY_SIZE(CEAM1920x1080)}
1086};
diff --git a/drivers/video/via/viamode.h b/drivers/video/via/viamode.h
new file mode 100644
index 000000000000..1a5de50a23a2
--- /dev/null
+++ b/drivers/video/via/viamode.h
@@ -0,0 +1,177 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
14 * for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22#ifndef __VIAMODE_H__
23#define __VIAMODE_H__
24
25#include "global.h"
26
27struct VPITTable {
28 unsigned char Misc;
29 unsigned char SR[StdSR];
30 unsigned char GR[StdGR];
31 unsigned char AR[StdAR];
32};
33
34struct VideoModeTable {
35 int ModeIndex;
36 struct crt_mode_table *crtc;
37 int mode_array;
38};
39
40struct patch_table {
41 int mode_index;
42 int table_length;
43 struct io_reg *io_reg_table;
44};
45
46struct res_map_refresh {
47 int hres;
48 int vres;
49 int pixclock;
50 int vmode_refresh;
51};
52
53#define NUM_TOTAL_RES_MAP_REFRESH ARRAY_SIZE(res_map_refresh_tbl)
54#define NUM_TOTAL_CEA_MODES ARRAY_SIZE(CEA_HDMI_Modes)
55#define NUM_TOTAL_CN400_ModeXregs ARRAY_SIZE(CN400_ModeXregs)
56#define NUM_TOTAL_CN700_ModeXregs ARRAY_SIZE(CN700_ModeXregs)
57#define NUM_TOTAL_KM400_ModeXregs ARRAY_SIZE(KM400_ModeXregs)
58#define NUM_TOTAL_CX700_ModeXregs ARRAY_SIZE(CX700_ModeXregs)
59#define NUM_TOTAL_VX800_ModeXregs ARRAY_SIZE(VX800_ModeXregs)
60#define NUM_TOTAL_CLE266_ModeXregs ARRAY_SIZE(CLE266_ModeXregs)
61#define NUM_TOTAL_PATCH_MODE ARRAY_SIZE(res_patch_table)
62#define NUM_TOTAL_MODETABLE ARRAY_SIZE(CLE266Modes)
63
64/********************/
65/* Mode Table */
66/********************/
67
68/* 480x640 */
69extern struct crt_mode_table CRTM480x640[1];
70/* 640x480*/
71extern struct crt_mode_table CRTM640x480[5];
72/*720x480 (GTF)*/
73extern struct crt_mode_table CRTM720x480[1];
74/*720x576 (GTF)*/
75extern struct crt_mode_table CRTM720x576[1];
76/* 800x480 (CVT) */
77extern struct crt_mode_table CRTM800x480[1];
78/* 800x600*/
79extern struct crt_mode_table CRTM800x600[5];
80/* 848x480 (CVT) */
81extern struct crt_mode_table CRTM848x480[1];
82/*856x480 (GTF) convert to 852x480*/
83extern struct crt_mode_table CRTM852x480[1];
84/*1024x512 (GTF)*/
85extern struct crt_mode_table CRTM1024x512[1];
86/* 1024x600*/
87extern struct crt_mode_table CRTM1024x600[1];
88/* 1024x768*/
89extern struct crt_mode_table CRTM1024x768[4];
90/* 1152x864*/
91extern struct crt_mode_table CRTM1152x864[1];
92/* 1280x720 (HDMI 720P)*/
93extern struct crt_mode_table CRTM1280x720[2];
94/*1280x768 (GTF)*/
95extern struct crt_mode_table CRTM1280x768[2];
96/* 1280x800 (CVT) */
97extern struct crt_mode_table CRTM1280x800[1];
98/*1280x960*/
99extern struct crt_mode_table CRTM1280x960[1];
100/* 1280x1024*/
101extern struct crt_mode_table CRTM1280x1024[3];
102/* 1368x768 (GTF) */
103extern struct crt_mode_table CRTM1368x768[1];
104/*1440x1050 (GTF)*/
105extern struct crt_mode_table CRTM1440x1050[1];
106/* 1600x1200*/
107extern struct crt_mode_table CRTM1600x1200[2];
108/* 1680x1050 (CVT) */
109extern struct crt_mode_table CRTM1680x1050[2];
110/* 1680x1050 (CVT Reduce Blanking) */
111extern struct crt_mode_table CRTM1680x1050_RB[1];
112/* 1920x1080 (CVT)*/
113extern struct crt_mode_table CRTM1920x1080[1];
114/* 1920x1080 (CVT with Reduce Blanking) */
115extern struct crt_mode_table CRTM1920x1080_RB[1];
116/* 1920x1440*/
117extern struct crt_mode_table CRTM1920x1440[2];
118/* 1400x1050 (CVT) */
119extern struct crt_mode_table CRTM1400x1050[2];
120/* 1400x1050 (CVT Reduce Blanking) */
121extern struct crt_mode_table CRTM1400x1050_RB[1];
122/* 960x600 (CVT) */
123extern struct crt_mode_table CRTM960x600[1];
124/* 1000x600 (GTF) */
125extern struct crt_mode_table CRTM1000x600[1];
126/* 1024x576 (GTF) */
127extern struct crt_mode_table CRTM1024x576[1];
128/* 1088x612 (CVT) */
129extern struct crt_mode_table CRTM1088x612[1];
130/* 1152x720 (CVT) */
131extern struct crt_mode_table CRTM1152x720[1];
132/* 1200x720 (GTF) */
133extern struct crt_mode_table CRTM1200x720[1];
134/* 1280x600 (GTF) */
135extern struct crt_mode_table CRTM1280x600[1];
136/* 1360x768 (CVT) */
137extern struct crt_mode_table CRTM1360x768[1];
138/* 1360x768 (CVT Reduce Blanking) */
139extern struct crt_mode_table CRTM1360x768_RB[1];
140/* 1366x768 (GTF) */
141extern struct crt_mode_table CRTM1366x768[2];
142/* 1440x900 (CVT) */
143extern struct crt_mode_table CRTM1440x900[2];
144/* 1440x900 (CVT Reduce Blanking) */
145extern struct crt_mode_table CRTM1440x900_RB[1];
146/* 1600x900 (CVT) */
147extern struct crt_mode_table CRTM1600x900[1];
148/* 1600x900 (CVT Reduce Blanking) */
149extern struct crt_mode_table CRTM1600x900_RB[1];
150/* 1600x1024 (GTF) */
151extern struct crt_mode_table CRTM1600x1024[1];
152/* 1792x1344 (DMT) */
153extern struct crt_mode_table CRTM1792x1344[1];
154/* 1856x1392 (DMT) */
155extern struct crt_mode_table CRTM1856x1392[1];
156/* 1920x1200 (CVT) */
157extern struct crt_mode_table CRTM1920x1200[1];
158/* 1920x1200 (CVT with Reduce Blanking) */
159extern struct crt_mode_table CRTM1920x1200_RB[1];
160/* 2048x1536 (CVT) */
161extern struct crt_mode_table CRTM2048x1536[1];
162extern struct VideoModeTable CLE266Modes[47];
163extern struct crt_mode_table CEAM1280x720[1];
164extern struct crt_mode_table CEAM1920x1080[1];
165extern struct VideoModeTable CEA_HDMI_Modes[2];
166
167extern struct res_map_refresh res_map_refresh_tbl[61];
168extern struct io_reg CN400_ModeXregs[52];
169extern struct io_reg CN700_ModeXregs[66];
170extern struct io_reg KM400_ModeXregs[55];
171extern struct io_reg CX700_ModeXregs[58];
172extern struct io_reg VX800_ModeXregs[58];
173extern struct io_reg CLE266_ModeXregs[32];
174extern struct io_reg PM1024x768[2];
175extern struct patch_table res_patch_table[1];
176extern struct VPITTable VPIT;
177#endif /* __VIAMODE_H__ */
diff --git a/drivers/video/via/vt1636.c b/drivers/video/via/vt1636.c
new file mode 100644
index 000000000000..322a9f993550
--- /dev/null
+++ b/drivers/video/via/vt1636.c
@@ -0,0 +1,306 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
14 * for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22#include "global.h"
23
24u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information
25 *plvds_setting_info, struct lvds_chip_information *plvds_chip_info,
26 u8 index)
27{
28 u8 data;
29
30 viaparinfo->i2c_stuff.i2c_port = plvds_chip_info->i2c_port;
31 viafb_i2c_readbyte(plvds_chip_info->lvds_chip_slave_addr, index, &data);
32
33 return data;
34}
35
36void viafb_gpio_i2c_write_mask_lvds(struct lvds_setting_information
37 *plvds_setting_info, struct lvds_chip_information
38 *plvds_chip_info, struct IODATA io_data)
39{
40 int index, data;
41
42 viaparinfo->i2c_stuff.i2c_port = plvds_chip_info->i2c_port;
43
44 index = io_data.Index;
45 data = viafb_gpio_i2c_read_lvds(plvds_setting_info, plvds_chip_info,
46 index);
47 data = (data & (~io_data.Mask)) | io_data.Data;
48
49 viafb_i2c_writebyte(plvds_chip_info->lvds_chip_slave_addr, index, data);
50}
51
52void viafb_init_lvds_vt1636(struct lvds_setting_information
53 *plvds_setting_info, struct lvds_chip_information *plvds_chip_info)
54{
55 int reg_num, i;
56
57 /* Common settings: */
58 reg_num = ARRAY_SIZE(COMMON_INIT_TBL_VT1636);
59
60 for (i = 0; i < reg_num; i++) {
61 viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
62 plvds_chip_info,
63 COMMON_INIT_TBL_VT1636[i]);
64 }
65
66 /* Input Data Mode Select */
67 if (plvds_setting_info->device_lcd_dualedge) {
68 viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
69 plvds_chip_info,
70 DUAL_CHANNEL_ENABLE_TBL_VT1636[0]);
71 } else {
72 viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
73 plvds_chip_info,
74 SINGLE_CHANNEL_ENABLE_TBL_VT1636[0]);
75 }
76
77 if (plvds_setting_info->LCDDithering) {
78 viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
79 plvds_chip_info,
80 DITHERING_ENABLE_TBL_VT1636[0]);
81 } else {
82 viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
83 plvds_chip_info,
84 DITHERING_DISABLE_TBL_VT1636[0]);
85 }
86}
87
88void viafb_enable_lvds_vt1636(struct lvds_setting_information
89 *plvds_setting_info,
90 struct lvds_chip_information *plvds_chip_info)
91{
92
93 viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info,
94 VDD_ON_TBL_VT1636[0]);
95
96 /* Pad on: */
97 switch (plvds_chip_info->output_interface) {
98 case INTERFACE_DVP0:
99 {
100 viafb_write_reg_mask(SR1E, VIASR, 0xC0, 0xC0);
101 break;
102 }
103
104 case INTERFACE_DVP1:
105 {
106 viafb_write_reg_mask(SR1E, VIASR, 0x30, 0x30);
107 break;
108 }
109
110 case INTERFACE_DFP_LOW:
111 {
112 viafb_write_reg_mask(SR2A, VIASR, 0x03, 0x03);
113 break;
114 }
115
116 case INTERFACE_DFP_HIGH:
117 {
118 viafb_write_reg_mask(SR2A, VIASR, 0x03, 0x0C);
119 break;
120 }
121
122 }
123}
124
125void viafb_disable_lvds_vt1636(struct lvds_setting_information
126 *plvds_setting_info,
127 struct lvds_chip_information *plvds_chip_info)
128{
129
130 viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info,
131 VDD_OFF_TBL_VT1636[0]);
132
133 /* Pad off: */
134 switch (plvds_chip_info->output_interface) {
135 case INTERFACE_DVP0:
136 {
137 viafb_write_reg_mask(SR1E, VIASR, 0x00, 0xC0);
138 break;
139 }
140
141 case INTERFACE_DVP1:
142 {
143 viafb_write_reg_mask(SR1E, VIASR, 0x00, 0x30);
144 break;
145 }
146
147 case INTERFACE_DFP_LOW:
148 {
149 viafb_write_reg_mask(SR2A, VIASR, 0x00, 0x03);
150 break;
151 }
152
153 case INTERFACE_DFP_HIGH:
154 {
155 viafb_write_reg_mask(SR2A, VIASR, 0x00, 0x0C);
156 break;
157 }
158
159 }
160}
161
162bool viafb_lvds_identify_vt1636(void)
163{
164 u8 Buffer[2];
165
166 DEBUG_MSG(KERN_INFO "viafb_lvds_identify_vt1636.\n");
167
168 /* Sense VT1636 LVDS Transmiter */
169 viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr =
170 VT1636_LVDS_I2C_ADDR;
171
172 /* Check vendor ID first: */
173 viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info.
174 lvds_chip_slave_addr,
175 0x00, &Buffer[0]);
176 viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info.
177 lvds_chip_slave_addr,
178 0x01, &Buffer[1]);
179
180 if (!((Buffer[0] == 0x06) && (Buffer[1] == 0x11)))
181 return false;
182
183 /* Check Chip ID: */
184 viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info.
185 lvds_chip_slave_addr,
186 0x02, &Buffer[0]);
187 viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info.
188 lvds_chip_slave_addr,
189 0x03, &Buffer[1]);
190 if ((Buffer[0] == 0x45) && (Buffer[1] == 0x33)) {
191 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
192 VT1636_LVDS;
193 return true;
194 }
195
196 return false;
197}
198
199static int get_clk_range_index(u32 Clk)
200{
201 if (Clk < DPA_CLK_30M)
202 return DPA_CLK_RANGE_30M;
203 else if (Clk < DPA_CLK_50M)
204 return DPA_CLK_RANGE_30_50M;
205 else if (Clk < DPA_CLK_70M)
206 return DPA_CLK_RANGE_50_70M;
207 else if (Clk < DPA_CLK_100M)
208 return DPA_CLK_RANGE_70_100M;
209 else if (Clk < DPA_CLK_150M)
210 return DPA_CLK_RANGE_100_150M;
211 else
212 return DPA_CLK_RANGE_150M;
213}
214
215static int get_lvds_dpa_setting_index(int panel_size_id,
216 struct VT1636_DPA_SETTING *p_vt1636_dpasetting_tbl,
217 int tbl_size)
218{
219 int i;
220
221 for (i = 0; i < tbl_size; i++) {
222 if (panel_size_id == p_vt1636_dpasetting_tbl->PanelSizeID)
223 return i;
224
225 p_vt1636_dpasetting_tbl++;
226 }
227
228 return 0;
229}
230
231static void set_dpa_vt1636(struct lvds_setting_information
232 *plvds_setting_info, struct lvds_chip_information *plvds_chip_info,
233 struct VT1636_DPA_SETTING *p_vt1636_dpa_setting)
234{
235 struct IODATA io_data;
236
237 io_data.Index = 0x09;
238 io_data.Mask = 0x1F;
239 io_data.Data = p_vt1636_dpa_setting->CLK_SEL_ST1;
240 viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
241 plvds_chip_info, io_data);
242
243 io_data.Index = 0x08;
244 io_data.Mask = 0x0F;
245 io_data.Data = p_vt1636_dpa_setting->CLK_SEL_ST2;
246 viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info,
247 io_data);
248}
249
250void viafb_vt1636_patch_skew_on_vt3324(
251 struct lvds_setting_information *plvds_setting_info,
252 struct lvds_chip_information *plvds_chip_info)
253{
254 int index, size;
255
256 DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3324.\n");
257
258 /* Graphics DPA settings: */
259 index = get_clk_range_index(plvds_setting_info->vclk);
260 viafb_set_dpa_gfx(plvds_chip_info->output_interface,
261 &GFX_DPA_SETTING_TBL_VT3324[index]);
262
263 /* LVDS Transmitter DPA settings: */
264 size = ARRAY_SIZE(VT1636_DPA_SETTING_TBL_VT3324);
265 index =
266 get_lvds_dpa_setting_index(plvds_setting_info->lcd_panel_id,
267 VT1636_DPA_SETTING_TBL_VT3324, size);
268 set_dpa_vt1636(plvds_setting_info, plvds_chip_info,
269 &VT1636_DPA_SETTING_TBL_VT3324[index]);
270}
271
272void viafb_vt1636_patch_skew_on_vt3327(
273 struct lvds_setting_information *plvds_setting_info,
274 struct lvds_chip_information *plvds_chip_info)
275{
276 int index, size;
277
278 DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3327.\n");
279
280 /* Graphics DPA settings: */
281 index = get_clk_range_index(plvds_setting_info->vclk);
282 viafb_set_dpa_gfx(plvds_chip_info->output_interface,
283 &GFX_DPA_SETTING_TBL_VT3327[index]);
284
285 /* LVDS Transmitter DPA settings: */
286 size = ARRAY_SIZE(VT1636_DPA_SETTING_TBL_VT3327);
287 index =
288 get_lvds_dpa_setting_index(plvds_setting_info->lcd_panel_id,
289 VT1636_DPA_SETTING_TBL_VT3327, size);
290 set_dpa_vt1636(plvds_setting_info, plvds_chip_info,
291 &VT1636_DPA_SETTING_TBL_VT3327[index]);
292}
293
294void viafb_vt1636_patch_skew_on_vt3364(
295 struct lvds_setting_information *plvds_setting_info,
296 struct lvds_chip_information *plvds_chip_info)
297{
298 int index;
299
300 DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3364.\n");
301
302 /* Graphics DPA settings: */
303 index = get_clk_range_index(plvds_setting_info->vclk);
304 viafb_set_dpa_gfx(plvds_chip_info->output_interface,
305 &GFX_DPA_SETTING_TBL_VT3364[index]);
306}
diff --git a/drivers/video/via/vt1636.h b/drivers/video/via/vt1636.h
new file mode 100644
index 000000000000..2a150c58c7ed
--- /dev/null
+++ b/drivers/video/via/vt1636.h
@@ -0,0 +1,44 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
14 * for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22#ifndef _VT1636_H_
23#define _VT1636_H_
24#include "chip.h"
25bool viafb_lvds_identify_vt1636(void);
26void viafb_init_lvds_vt1636(struct lvds_setting_information
27 *plvds_setting_info, struct lvds_chip_information *plvds_chip_info);
28void viafb_enable_lvds_vt1636(struct lvds_setting_information
29 *plvds_setting_info,
30 struct lvds_chip_information *plvds_chip_info);
31void viafb_disable_lvds_vt1636(struct lvds_setting_information
32 *plvds_setting_info,
33 struct lvds_chip_information *plvds_chip_info);
34void viafb_vt1636_patch_skew_on_vt3324(
35 struct lvds_setting_information *plvds_setting_info,
36 struct lvds_chip_information *plvds_chip_info);
37void viafb_vt1636_patch_skew_on_vt3327(
38 struct lvds_setting_information *plvds_setting_info,
39 struct lvds_chip_information *plvds_chip_info);
40void viafb_vt1636_patch_skew_on_vt3364(
41 struct lvds_setting_information *plvds_setting_info,
42 struct lvds_chip_information *plvds_chip_info);
43
44#endif
diff --git a/drivers/w1/masters/ds1wm.c b/drivers/w1/masters/ds1wm.c
index 10211e493001..29e144f81cbe 100644
--- a/drivers/w1/masters/ds1wm.c
+++ b/drivers/w1/masters/ds1wm.c
@@ -160,8 +160,10 @@ static int ds1wm_reset(struct ds1wm_data *ds1wm_data)
160 * 625 us - 60 us - 240 us - 100 ns = 324.9 us 160 * 625 us - 60 us - 240 us - 100 ns = 324.9 us
161 * 161 *
162 * We'll wait a bit longer just to be sure. 162 * We'll wait a bit longer just to be sure.
163 * Was udelay(500), but if it is going to busywait the cpu that long,
164 * might as well come back later.
163 */ 165 */
164 udelay(500); 166 msleep(1);
165 167
166 ds1wm_write_register(ds1wm_data, DS1WM_INT_EN, 168 ds1wm_write_register(ds1wm_data, DS1WM_INT_EN,
167 DS1WM_INTEN_ERBF | DS1WM_INTEN_ETMT | DS1WM_INTEN_EPD | 169 DS1WM_INTEN_ERBF | DS1WM_INTEN_ETMT | DS1WM_INTEN_EPD |
@@ -274,8 +276,8 @@ static u8 ds1wm_reset_bus(void *data)
274 return 0; 276 return 0;
275} 277}
276 278
277static void ds1wm_search(void *data, u8 search_type, 279static void ds1wm_search(void *data, struct w1_master *master_dev,
278 w1_slave_found_callback slave_found) 280 u8 search_type, w1_slave_found_callback slave_found)
279{ 281{
280 struct ds1wm_data *ds1wm_data = data; 282 struct ds1wm_data *ds1wm_data = data;
281 int i; 283 int i;
@@ -313,7 +315,7 @@ static void ds1wm_search(void *data, u8 search_type,
313 ds1wm_write_register(ds1wm_data, DS1WM_CMD, ~DS1WM_CMD_SRA); 315 ds1wm_write_register(ds1wm_data, DS1WM_CMD, ~DS1WM_CMD_SRA);
314 ds1wm_reset(ds1wm_data); 316 ds1wm_reset(ds1wm_data);
315 317
316 slave_found(ds1wm_data, rom_id); 318 slave_found(master_dev, rom_id);
317} 319}
318 320
319/* --------------------------------------------------------------------- */ 321/* --------------------------------------------------------------------- */
diff --git a/drivers/w1/masters/ds2490.c b/drivers/w1/masters/ds2490.c
index b63b5e044a4c..59ad6e95af8f 100644
--- a/drivers/w1/masters/ds2490.c
+++ b/drivers/w1/masters/ds2490.c
@@ -88,7 +88,7 @@
88#define COMM_DT 0x2000 88#define COMM_DT 0x2000
89#define COMM_SPU 0x1000 89#define COMM_SPU 0x1000
90#define COMM_F 0x0800 90#define COMM_F 0x0800
91#define COMM_NTP 0x0400 91#define COMM_NTF 0x0400
92#define COMM_ICP 0x0200 92#define COMM_ICP 0x0200
93#define COMM_RST 0x0100 93#define COMM_RST 0x0100
94 94
@@ -98,11 +98,6 @@
98#define BRANCH_MAIN 0xCC 98#define BRANCH_MAIN 0xCC
99#define BRANCH_AUX 0x33 99#define BRANCH_AUX 0x33
100 100
101/*
102 * Duration of the strong pull-up pulse in milliseconds.
103 */
104#define PULLUP_PULSE_DURATION 750
105
106/* Status flags */ 101/* Status flags */
107#define ST_SPUA 0x01 /* Strong Pull-up is active */ 102#define ST_SPUA 0x01 /* Strong Pull-up is active */
108#define ST_PRGA 0x02 /* 12V programming pulse is being generated */ 103#define ST_PRGA 0x02 /* 12V programming pulse is being generated */
@@ -112,6 +107,17 @@
112#define ST_IDLE 0x20 /* DS2490 is currently idle */ 107#define ST_IDLE 0x20 /* DS2490 is currently idle */
113#define ST_EPOF 0x80 108#define ST_EPOF 0x80
114 109
110/* Result Register flags */
111#define RR_DETECT 0xA5 /* New device detected */
112#define RR_NRS 0x01 /* Reset no presence or ... */
113#define RR_SH 0x02 /* short on reset or set path */
114#define RR_APP 0x04 /* alarming presence on reset */
115#define RR_VPP 0x08 /* 12V expected not seen */
116#define RR_CMP 0x10 /* compare error */
117#define RR_CRC 0x20 /* CRC error detected */
118#define RR_RDP 0x40 /* redirected page */
119#define RR_EOS 0x80 /* end of search error */
120
115#define SPEED_NORMAL 0x00 121#define SPEED_NORMAL 0x00
116#define SPEED_FLEXIBLE 0x01 122#define SPEED_FLEXIBLE 0x01
117#define SPEED_OVERDRIVE 0x02 123#define SPEED_OVERDRIVE 0x02
@@ -131,6 +137,15 @@ struct ds_device
131 137
132 int ep[NUM_EP]; 138 int ep[NUM_EP];
133 139
140 /* Strong PullUp
141 * 0: pullup not active, else duration in milliseconds
142 */
143 int spu_sleep;
144 /* spu_bit contains COMM_SPU or 0 depending on if the strong pullup
145 * should be active or not for writes.
146 */
147 u16 spu_bit;
148
134 struct w1_bus_master master; 149 struct w1_bus_master master;
135}; 150};
136 151
@@ -164,7 +179,6 @@ MODULE_DEVICE_TABLE(usb, ds_id_table);
164static int ds_probe(struct usb_interface *, const struct usb_device_id *); 179static int ds_probe(struct usb_interface *, const struct usb_device_id *);
165static void ds_disconnect(struct usb_interface *); 180static void ds_disconnect(struct usb_interface *);
166 181
167static inline void ds_dump_status(unsigned char *, unsigned char *, int);
168static int ds_send_control(struct ds_device *, u16, u16); 182static int ds_send_control(struct ds_device *, u16, u16);
169static int ds_send_control_cmd(struct ds_device *, u16, u16); 183static int ds_send_control_cmd(struct ds_device *, u16, u16);
170 184
@@ -192,7 +206,7 @@ static int ds_send_control_cmd(struct ds_device *dev, u16 value, u16 index)
192 206
193 return err; 207 return err;
194} 208}
195#if 0 209
196static int ds_send_control_mode(struct ds_device *dev, u16 value, u16 index) 210static int ds_send_control_mode(struct ds_device *dev, u16 value, u16 index)
197{ 211{
198 int err; 212 int err;
@@ -207,7 +221,7 @@ static int ds_send_control_mode(struct ds_device *dev, u16 value, u16 index)
207 221
208 return err; 222 return err;
209} 223}
210#endif 224
211static int ds_send_control(struct ds_device *dev, u16 value, u16 index) 225static int ds_send_control(struct ds_device *dev, u16 value, u16 index)
212{ 226{
213 int err; 227 int err;
@@ -223,11 +237,6 @@ static int ds_send_control(struct ds_device *dev, u16 value, u16 index)
223 return err; 237 return err;
224} 238}
225 239
226static inline void ds_dump_status(unsigned char *buf, unsigned char *str, int off)
227{
228 printk("%45s: %8x\n", str, buf[off]);
229}
230
231static int ds_recv_status_nodump(struct ds_device *dev, struct ds_status *st, 240static int ds_recv_status_nodump(struct ds_device *dev, struct ds_status *st,
232 unsigned char *buf, int size) 241 unsigned char *buf, int size)
233{ 242{
@@ -248,62 +257,81 @@ static int ds_recv_status_nodump(struct ds_device *dev, struct ds_status *st,
248 return count; 257 return count;
249} 258}
250 259
251static int ds_recv_status(struct ds_device *dev, struct ds_status *st) 260static inline void ds_print_msg(unsigned char *buf, unsigned char *str, int off)
252{ 261{
253 unsigned char buf[64]; 262 printk(KERN_INFO "%45s: %8x\n", str, buf[off]);
254 int count, err = 0, i; 263}
255
256 memcpy(st, buf, sizeof(*st));
257 264
258 count = ds_recv_status_nodump(dev, st, buf, sizeof(buf)); 265static void ds_dump_status(struct ds_device *dev, unsigned char *buf, int count)
259 if (count < 0) 266{
260 return err; 267 int i;
261 268
262 printk("0x%x: count=%d, status: ", dev->ep[EP_STATUS], count); 269 printk(KERN_INFO "0x%x: count=%d, status: ", dev->ep[EP_STATUS], count);
263 for (i=0; i<count; ++i) 270 for (i=0; i<count; ++i)
264 printk("%02x ", buf[i]); 271 printk("%02x ", buf[i]);
265 printk("\n"); 272 printk(KERN_INFO "\n");
266 273
267 if (count >= 16) { 274 if (count >= 16) {
268 ds_dump_status(buf, "enable flag", 0); 275 ds_print_msg(buf, "enable flag", 0);
269 ds_dump_status(buf, "1-wire speed", 1); 276 ds_print_msg(buf, "1-wire speed", 1);
270 ds_dump_status(buf, "strong pullup duration", 2); 277 ds_print_msg(buf, "strong pullup duration", 2);
271 ds_dump_status(buf, "programming pulse duration", 3); 278 ds_print_msg(buf, "programming pulse duration", 3);
272 ds_dump_status(buf, "pulldown slew rate control", 4); 279 ds_print_msg(buf, "pulldown slew rate control", 4);
273 ds_dump_status(buf, "write-1 low time", 5); 280 ds_print_msg(buf, "write-1 low time", 5);
274 ds_dump_status(buf, "data sample offset/write-0 recovery time", 6); 281 ds_print_msg(buf, "data sample offset/write-0 recovery time",
275 ds_dump_status(buf, "reserved (test register)", 7); 282 6);
276 ds_dump_status(buf, "device status flags", 8); 283 ds_print_msg(buf, "reserved (test register)", 7);
277 ds_dump_status(buf, "communication command byte 1", 9); 284 ds_print_msg(buf, "device status flags", 8);
278 ds_dump_status(buf, "communication command byte 2", 10); 285 ds_print_msg(buf, "communication command byte 1", 9);
279 ds_dump_status(buf, "communication command buffer status", 11); 286 ds_print_msg(buf, "communication command byte 2", 10);
280 ds_dump_status(buf, "1-wire data output buffer status", 12); 287 ds_print_msg(buf, "communication command buffer status", 11);
281 ds_dump_status(buf, "1-wire data input buffer status", 13); 288 ds_print_msg(buf, "1-wire data output buffer status", 12);
282 ds_dump_status(buf, "reserved", 14); 289 ds_print_msg(buf, "1-wire data input buffer status", 13);
283 ds_dump_status(buf, "reserved", 15); 290 ds_print_msg(buf, "reserved", 14);
291 ds_print_msg(buf, "reserved", 15);
284 } 292 }
285 293 for (i = 16; i < count; ++i) {
286 memcpy(st, buf, sizeof(*st)); 294 if (buf[i] == RR_DETECT) {
287 295 ds_print_msg(buf, "new device detect", i);
288 if (st->status & ST_EPOF) { 296 continue;
289 printk(KERN_INFO "Resetting device after ST_EPOF.\n"); 297 }
290 err = ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0); 298 ds_print_msg(buf, "Result Register Value: ", i);
291 if (err) 299 if (buf[i] & RR_NRS)
292 return err; 300 printk(KERN_INFO "NRS: Reset no presence or ...\n");
293 count = ds_recv_status_nodump(dev, st, buf, sizeof(buf)); 301 if (buf[i] & RR_SH)
294 if (count < 0) 302 printk(KERN_INFO "SH: short on reset or set path\n");
295 return err; 303 if (buf[i] & RR_APP)
296 } 304 printk(KERN_INFO "APP: alarming presence on reset\n");
297#if 0 305 if (buf[i] & RR_VPP)
298 if (st->status & ST_IDLE) { 306 printk(KERN_INFO "VPP: 12V expected not seen\n");
299 printk(KERN_INFO "Resetting pulse after ST_IDLE.\n"); 307 if (buf[i] & RR_CMP)
300 err = ds_start_pulse(dev, PULLUP_PULSE_DURATION); 308 printk(KERN_INFO "CMP: compare error\n");
301 if (err) 309 if (buf[i] & RR_CRC)
302 return err; 310 printk(KERN_INFO "CRC: CRC error detected\n");
311 if (buf[i] & RR_RDP)
312 printk(KERN_INFO "RDP: redirected page\n");
313 if (buf[i] & RR_EOS)
314 printk(KERN_INFO "EOS: end of search error\n");
303 } 315 }
304#endif 316}
305 317
306 return err; 318static void ds_reset_device(struct ds_device *dev)
319{
320 ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0);
321 /* Always allow strong pullup which allow individual writes to use
322 * the strong pullup.
323 */
324 if (ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_SPUE))
325 printk(KERN_ERR "ds_reset_device: "
326 "Error allowing strong pullup\n");
327 /* Chip strong pullup time was cleared. */
328 if (dev->spu_sleep) {
329 /* lower 4 bits are 0, see ds_set_pullup */
330 u8 del = dev->spu_sleep>>4;
331 if (ds_send_control(dev, COMM_SET_DURATION | COMM_IM, del))
332 printk(KERN_ERR "ds_reset_device: "
333 "Error setting duration\n");
334 }
307} 335}
308 336
309static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size) 337static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size)
@@ -311,13 +339,27 @@ static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size)
311 int count, err; 339 int count, err;
312 struct ds_status st; 340 struct ds_status st;
313 341
342 /* Careful on size. If size is less than what is available in
343 * the input buffer, the device fails the bulk transfer and
344 * clears the input buffer. It could read the maximum size of
345 * the data buffer, but then do you return the first, last, or
346 * some set of the middle size bytes? As long as the rest of
347 * the code is correct there will be size bytes waiting. A
348 * call to ds_wait_status will wait until the device is idle
349 * and any data to be received would have been available.
350 */
314 count = 0; 351 count = 0;
315 err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]), 352 err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]),
316 buf, size, &count, 1000); 353 buf, size, &count, 1000);
317 if (err < 0) { 354 if (err < 0) {
355 u8 buf[0x20];
356 int count;
357
318 printk(KERN_INFO "Clearing ep0x%x.\n", dev->ep[EP_DATA_IN]); 358 printk(KERN_INFO "Clearing ep0x%x.\n", dev->ep[EP_DATA_IN]);
319 usb_clear_halt(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN])); 359 usb_clear_halt(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]));
320 ds_recv_status(dev, &st); 360
361 count = ds_recv_status_nodump(dev, &st, buf, sizeof(buf));
362 ds_dump_status(dev, buf, count);
321 return err; 363 return err;
322 } 364 }
323 365
@@ -341,7 +383,8 @@ static int ds_send_data(struct ds_device *dev, unsigned char *buf, int len)
341 count = 0; 383 count = 0;
342 err = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, dev->ep[EP_DATA_OUT]), buf, len, &count, 1000); 384 err = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, dev->ep[EP_DATA_OUT]), buf, len, &count, 1000);
343 if (err < 0) { 385 if (err < 0) {
344 printk(KERN_ERR "Failed to read 1-wire data from 0x02: err=%d.\n", err); 386 printk(KERN_ERR "Failed to write 1-wire data to ep0x%x: "
387 "err=%d.\n", dev->ep[EP_DATA_OUT], err);
345 return err; 388 return err;
346 } 389 }
347 390
@@ -397,7 +440,7 @@ int ds_detect(struct ds_device *dev, struct ds_status *st)
397 if (err) 440 if (err)
398 return err; 441 return err;
399 442
400 err = ds_recv_status(dev, st); 443 err = ds_dump_status(dev, st);
401 444
402 return err; 445 return err;
403} 446}
@@ -420,33 +463,49 @@ static int ds_wait_status(struct ds_device *dev, struct ds_status *st)
420 printk("\n"); 463 printk("\n");
421 } 464 }
422#endif 465#endif
423 } while(!(buf[0x08] & 0x20) && !(err < 0) && ++count < 100); 466 } while (!(buf[0x08] & ST_IDLE) && !(err < 0) && ++count < 100);
467
468 if (err >= 16 && st->status & ST_EPOF) {
469 printk(KERN_INFO "Resetting device after ST_EPOF.\n");
470 ds_reset_device(dev);
471 /* Always dump the device status. */
472 count = 101;
473 }
424 474
475 /* Dump the status for errors or if there is extended return data.
476 * The extended status includes new device detection (maybe someone
477 * can do something with it).
478 */
479 if (err > 16 || count >= 100 || err < 0)
480 ds_dump_status(dev, buf, err);
425 481
426 if (((err > 16) && (buf[0x10] & 0x01)) || count >= 100 || err < 0) { 482 /* Extended data isn't an error. Well, a short is, but the dump
427 ds_recv_status(dev, st); 483 * would have already told the user that and we can't do anything
484 * about it in software anyway.
485 */
486 if (count >= 100 || err < 0)
428 return -1; 487 return -1;
429 } else 488 else
430 return 0; 489 return 0;
431} 490}
432 491
433static int ds_reset(struct ds_device *dev, struct ds_status *st) 492static int ds_reset(struct ds_device *dev)
434{ 493{
435 int err; 494 int err;
436 495
437 //err = ds_send_control(dev, COMM_1_WIRE_RESET | COMM_F | COMM_IM | COMM_SE, SPEED_FLEXIBLE); 496 /* Other potentionally interesting flags for reset.
438 err = ds_send_control(dev, 0x43, SPEED_NORMAL); 497 *
498 * COMM_NTF: Return result register feedback. This could be used to
499 * detect some conditions such as short, alarming presence, or
500 * detect if a new device was detected.
501 *
502 * COMM_SE which allows SPEED_NORMAL, SPEED_FLEXIBLE, SPEED_OVERDRIVE:
503 * Select the data transfer rate.
504 */
505 err = ds_send_control(dev, COMM_1_WIRE_RESET | COMM_IM, SPEED_NORMAL);
439 if (err) 506 if (err)
440 return err; 507 return err;
441 508
442 ds_wait_status(dev, st);
443#if 0
444 if (st->command_buffer_status) {
445 printk(KERN_INFO "Short circuit.\n");
446 return -EIO;
447 }
448#endif
449
450 return 0; 509 return 0;
451} 510}
452 511
@@ -471,60 +530,43 @@ static int ds_set_speed(struct ds_device *dev, int speed)
471} 530}
472#endif /* 0 */ 531#endif /* 0 */
473 532
474static int ds_start_pulse(struct ds_device *dev, int delay) 533static int ds_set_pullup(struct ds_device *dev, int delay)
475{ 534{
476 int err; 535 int err = 0;
477 u8 del = 1 + (u8)(delay >> 4); 536 u8 del = 1 + (u8)(delay >> 4);
478 struct ds_status st; 537 /* Just storing delay would not get the trunication and roundup. */
479 538 int ms = del<<4;
480#if 0 539
481 err = ds_stop_pulse(dev, 10); 540 /* Enable spu_bit if a delay is set. */
482 if (err) 541 dev->spu_bit = delay ? COMM_SPU : 0;
542 /* If delay is zero, it has already been disabled, if the time is
543 * the same as the hardware was last programmed to, there is also
544 * nothing more to do. Compare with the recalculated value ms
545 * rather than del or delay which can have a different value.
546 */
547 if (delay == 0 || ms == dev->spu_sleep)
483 return err; 548 return err;
484 549
485 err = ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_SPUE);
486 if (err)
487 return err;
488#endif
489 err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM, del); 550 err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM, del);
490 if (err) 551 if (err)
491 return err; 552 return err;
492 553
493 err = ds_send_control(dev, COMM_PULSE | COMM_IM | COMM_F, 0); 554 dev->spu_sleep = ms;
494 if (err)
495 return err;
496
497 mdelay(delay);
498
499 ds_wait_status(dev, &st);
500 555
501 return err; 556 return err;
502} 557}
503 558
504static int ds_touch_bit(struct ds_device *dev, u8 bit, u8 *tbit) 559static int ds_touch_bit(struct ds_device *dev, u8 bit, u8 *tbit)
505{ 560{
506 int err, count; 561 int err;
507 struct ds_status st; 562 struct ds_status st;
508 u16 value = (COMM_BIT_IO | COMM_IM) | ((bit) ? COMM_D : 0);
509 u16 cmd;
510 563
511 err = ds_send_control(dev, value, 0); 564 err = ds_send_control(dev, COMM_BIT_IO | COMM_IM | (bit ? COMM_D : 0),
565 0);
512 if (err) 566 if (err)
513 return err; 567 return err;
514 568
515 count = 0; 569 ds_wait_status(dev, &st);
516 do {
517 err = ds_wait_status(dev, &st);
518 if (err)
519 return err;
520
521 cmd = st.command0 | (st.command1 << 8);
522 } while (cmd != value && ++count < 10);
523
524 if (err < 0 || count >= 10) {
525 printk(KERN_ERR "Failed to obtain status.\n");
526 return -EINVAL;
527 }
528 570
529 err = ds_recv_data(dev, tbit, sizeof(*tbit)); 571 err = ds_recv_data(dev, tbit, sizeof(*tbit));
530 if (err < 0) 572 if (err < 0)
@@ -533,12 +575,18 @@ static int ds_touch_bit(struct ds_device *dev, u8 bit, u8 *tbit)
533 return 0; 575 return 0;
534} 576}
535 577
578#if 0
536static int ds_write_bit(struct ds_device *dev, u8 bit) 579static int ds_write_bit(struct ds_device *dev, u8 bit)
537{ 580{
538 int err; 581 int err;
539 struct ds_status st; 582 struct ds_status st;
540 583
541 err = ds_send_control(dev, COMM_BIT_IO | COMM_IM | (bit) ? COMM_D : 0, 0); 584 /* Set COMM_ICP to write without a readback. Note, this will
585 * produce one time slot, a down followed by an up with COMM_D
586 * only determing the timing.
587 */
588 err = ds_send_control(dev, COMM_BIT_IO | COMM_IM | COMM_ICP |
589 (bit ? COMM_D : 0), 0);
542 if (err) 590 if (err)
543 return err; 591 return err;
544 592
@@ -546,6 +594,7 @@ static int ds_write_bit(struct ds_device *dev, u8 bit)
546 594
547 return 0; 595 return 0;
548} 596}
597#endif
549 598
550static int ds_write_byte(struct ds_device *dev, u8 byte) 599static int ds_write_byte(struct ds_device *dev, u8 byte)
551{ 600{
@@ -553,10 +602,13 @@ static int ds_write_byte(struct ds_device *dev, u8 byte)
553 struct ds_status st; 602 struct ds_status st;
554 u8 rbyte; 603 u8 rbyte;
555 604
556 err = ds_send_control(dev, COMM_BYTE_IO | COMM_IM | COMM_SPU, byte); 605 err = ds_send_control(dev, COMM_BYTE_IO | COMM_IM | dev->spu_bit, byte);
557 if (err) 606 if (err)
558 return err; 607 return err;
559 608
609 if (dev->spu_bit)
610 msleep(dev->spu_sleep);
611
560 err = ds_wait_status(dev, &st); 612 err = ds_wait_status(dev, &st);
561 if (err) 613 if (err)
562 return err; 614 return err;
@@ -565,8 +617,6 @@ static int ds_write_byte(struct ds_device *dev, u8 byte)
565 if (err < 0) 617 if (err < 0)
566 return err; 618 return err;
567 619
568 ds_start_pulse(dev, PULLUP_PULSE_DURATION);
569
570 return !(byte == rbyte); 620 return !(byte == rbyte);
571} 621}
572 622
@@ -602,7 +652,7 @@ static int ds_read_block(struct ds_device *dev, u8 *buf, int len)
602 if (err < 0) 652 if (err < 0)
603 return err; 653 return err;
604 654
605 err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM | COMM_SPU, len); 655 err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM, len);
606 if (err) 656 if (err)
607 return err; 657 return err;
608 658
@@ -623,20 +673,19 @@ static int ds_write_block(struct ds_device *dev, u8 *buf, int len)
623 if (err < 0) 673 if (err < 0)
624 return err; 674 return err;
625 675
626 ds_wait_status(dev, &st); 676 err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM | dev->spu_bit, len);
627
628 err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM | COMM_SPU, len);
629 if (err) 677 if (err)
630 return err; 678 return err;
631 679
680 if (dev->spu_bit)
681 msleep(dev->spu_sleep);
682
632 ds_wait_status(dev, &st); 683 ds_wait_status(dev, &st);
633 684
634 err = ds_recv_data(dev, buf, len); 685 err = ds_recv_data(dev, buf, len);
635 if (err < 0) 686 if (err < 0)
636 return err; 687 return err;
637 688
638 ds_start_pulse(dev, PULLUP_PULSE_DURATION);
639
640 return !(err == len); 689 return !(err == len);
641} 690}
642 691
@@ -728,6 +777,7 @@ static u8 ds9490r_touch_bit(void *data, u8 bit)
728 return ret; 777 return ret;
729} 778}
730 779
780#if 0
731static void ds9490r_write_bit(void *data, u8 bit) 781static void ds9490r_write_bit(void *data, u8 bit)
732{ 782{
733 struct ds_device *dev = data; 783 struct ds_device *dev = data;
@@ -735,13 +785,6 @@ static void ds9490r_write_bit(void *data, u8 bit)
735 ds_write_bit(dev, bit); 785 ds_write_bit(dev, bit);
736} 786}
737 787
738static void ds9490r_write_byte(void *data, u8 byte)
739{
740 struct ds_device *dev = data;
741
742 ds_write_byte(dev, byte);
743}
744
745static u8 ds9490r_read_bit(void *data) 788static u8 ds9490r_read_bit(void *data)
746{ 789{
747 struct ds_device *dev = data; 790 struct ds_device *dev = data;
@@ -754,6 +797,14 @@ static u8 ds9490r_read_bit(void *data)
754 797
755 return bit & 1; 798 return bit & 1;
756} 799}
800#endif
801
802static void ds9490r_write_byte(void *data, u8 byte)
803{
804 struct ds_device *dev = data;
805
806 ds_write_byte(dev, byte);
807}
757 808
758static u8 ds9490r_read_byte(void *data) 809static u8 ds9490r_read_byte(void *data)
759{ 810{
@@ -790,31 +841,58 @@ static u8 ds9490r_read_block(void *data, u8 *buf, int len)
790static u8 ds9490r_reset(void *data) 841static u8 ds9490r_reset(void *data)
791{ 842{
792 struct ds_device *dev = data; 843 struct ds_device *dev = data;
793 struct ds_status st;
794 int err; 844 int err;
795 845
796 memset(&st, 0, sizeof(st)); 846 err = ds_reset(dev);
797
798 err = ds_reset(dev, &st);
799 if (err) 847 if (err)
800 return 1; 848 return 1;
801 849
802 return 0; 850 return 0;
803} 851}
804 852
853static u8 ds9490r_set_pullup(void *data, int delay)
854{
855 struct ds_device *dev = data;
856
857 if (ds_set_pullup(dev, delay))
858 return 1;
859
860 return 0;
861}
862
805static int ds_w1_init(struct ds_device *dev) 863static int ds_w1_init(struct ds_device *dev)
806{ 864{
807 memset(&dev->master, 0, sizeof(struct w1_bus_master)); 865 memset(&dev->master, 0, sizeof(struct w1_bus_master));
808 866
867 /* Reset the device as it can be in a bad state.
868 * This is necessary because a block write will wait for data
869 * to be placed in the output buffer and block any later
870 * commands which will keep accumulating and the device will
871 * not be idle. Another case is removing the ds2490 module
872 * while a bus search is in progress, somehow a few commands
873 * get through, but the input transfers fail leaving data in
874 * the input buffer. This will cause the next read to fail
875 * see the note in ds_recv_data.
876 */
877 ds_reset_device(dev);
878
809 dev->master.data = dev; 879 dev->master.data = dev;
810 dev->master.touch_bit = &ds9490r_touch_bit; 880 dev->master.touch_bit = &ds9490r_touch_bit;
881 /* read_bit and write_bit in w1_bus_master are expected to set and
882 * sample the line level. For write_bit that means it is expected to
883 * set it to that value and leave it there. ds2490 only supports an
884 * individual time slot at the lowest level. The requirement from
885 * pulling the bus state down to reading the state is 15us, something
886 * that isn't realistic on the USB bus anyway.
811 dev->master.read_bit = &ds9490r_read_bit; 887 dev->master.read_bit = &ds9490r_read_bit;
812 dev->master.write_bit = &ds9490r_write_bit; 888 dev->master.write_bit = &ds9490r_write_bit;
889 */
813 dev->master.read_byte = &ds9490r_read_byte; 890 dev->master.read_byte = &ds9490r_read_byte;
814 dev->master.write_byte = &ds9490r_write_byte; 891 dev->master.write_byte = &ds9490r_write_byte;
815 dev->master.read_block = &ds9490r_read_block; 892 dev->master.read_block = &ds9490r_read_block;
816 dev->master.write_block = &ds9490r_write_block; 893 dev->master.write_block = &ds9490r_write_block;
817 dev->master.reset_bus = &ds9490r_reset; 894 dev->master.reset_bus = &ds9490r_reset;
895 dev->master.set_pullup = &ds9490r_set_pullup;
818 896
819 return w1_add_master_device(&dev->master); 897 return w1_add_master_device(&dev->master);
820} 898}
@@ -838,6 +916,8 @@ static int ds_probe(struct usb_interface *intf,
838 printk(KERN_INFO "Failed to allocate new DS9490R structure.\n"); 916 printk(KERN_INFO "Failed to allocate new DS9490R structure.\n");
839 return -ENOMEM; 917 return -ENOMEM;
840 } 918 }
919 dev->spu_sleep = 0;
920 dev->spu_bit = 0;
841 dev->udev = usb_get_dev(udev); 921 dev->udev = usb_get_dev(udev);
842 if (!dev->udev) { 922 if (!dev->udev) {
843 err = -ENOMEM; 923 err = -ENOMEM;
diff --git a/drivers/w1/slaves/w1_ds2431.c b/drivers/w1/slaves/w1_ds2431.c
new file mode 100644
index 000000000000..2c6c0cf6a20f
--- /dev/null
+++ b/drivers/w1/slaves/w1_ds2431.c
@@ -0,0 +1,312 @@
1/*
2 * w1_ds2431.c - w1 family 2d (DS2431) driver
3 *
4 * Copyright (c) 2008 Bernhard Weirich <bernhard.weirich@riedel.net>
5 *
6 * Heavily inspired by w1_DS2433 driver from Ben Gardner <bgardner@wabtec.com>
7 *
8 * This source code is licensed under the GNU General Public License,
9 * Version 2. See the file COPYING for more details.
10 */
11
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/device.h>
16#include <linux/types.h>
17#include <linux/delay.h>
18
19#include "../w1.h"
20#include "../w1_int.h"
21#include "../w1_family.h"
22
23#define W1_F2D_EEPROM_SIZE 128
24#define W1_F2D_PAGE_COUNT 4
25#define W1_F2D_PAGE_BITS 5
26#define W1_F2D_PAGE_SIZE (1<<W1_F2D_PAGE_BITS)
27#define W1_F2D_PAGE_MASK 0x1F
28
29#define W1_F2D_SCRATCH_BITS 3
30#define W1_F2D_SCRATCH_SIZE (1<<W1_F2D_SCRATCH_BITS)
31#define W1_F2D_SCRATCH_MASK (W1_F2D_SCRATCH_SIZE-1)
32
33#define W1_F2D_READ_EEPROM 0xF0
34#define W1_F2D_WRITE_SCRATCH 0x0F
35#define W1_F2D_READ_SCRATCH 0xAA
36#define W1_F2D_COPY_SCRATCH 0x55
37
38
39#define W1_F2D_TPROG_MS 11
40
41#define W1_F2D_READ_RETRIES 10
42#define W1_F2D_READ_MAXLEN 8
43
44/*
45 * Check the file size bounds and adjusts count as needed.
46 * This would not be needed if the file size didn't reset to 0 after a write.
47 */
48static inline size_t w1_f2d_fix_count(loff_t off, size_t count, size_t size)
49{
50 if (off > size)
51 return 0;
52
53 if ((off + count) > size)
54 return size - off;
55
56 return count;
57}
58
59/*
60 * Read a block from W1 ROM two times and compares the results.
61 * If they are equal they are returned, otherwise the read
62 * is repeated W1_F2D_READ_RETRIES times.
63 *
64 * count must not exceed W1_F2D_READ_MAXLEN.
65 */
66static int w1_f2d_readblock(struct w1_slave *sl, int off, int count, char *buf)
67{
68 u8 wrbuf[3];
69 u8 cmp[W1_F2D_READ_MAXLEN];
70 int tries = W1_F2D_READ_RETRIES;
71
72 do {
73 wrbuf[0] = W1_F2D_READ_EEPROM;
74 wrbuf[1] = off & 0xff;
75 wrbuf[2] = off >> 8;
76
77 if (w1_reset_select_slave(sl))
78 return -1;
79
80 w1_write_block(sl->master, wrbuf, 3);
81 w1_read_block(sl->master, buf, count);
82
83 if (w1_reset_select_slave(sl))
84 return -1;
85
86 w1_write_block(sl->master, wrbuf, 3);
87 w1_read_block(sl->master, cmp, count);
88
89 if (!memcmp(cmp, buf, count))
90 return 0;
91 } while (--tries);
92
93 dev_err(&sl->dev, "proof reading failed %d times\n",
94 W1_F2D_READ_RETRIES);
95
96 return -1;
97}
98
99static ssize_t w1_f2d_read_bin(struct kobject *kobj,
100 struct bin_attribute *bin_attr,
101 char *buf, loff_t off, size_t count)
102{
103 struct w1_slave *sl = kobj_to_w1_slave(kobj);
104 int todo = count;
105
106 count = w1_f2d_fix_count(off, count, W1_F2D_EEPROM_SIZE);
107 if (count == 0)
108 return 0;
109
110 mutex_lock(&sl->master->mutex);
111
112 /* read directly from the EEPROM in chunks of W1_F2D_READ_MAXLEN */
113 while (todo > 0) {
114 int block_read;
115
116 if (todo >= W1_F2D_READ_MAXLEN)
117 block_read = W1_F2D_READ_MAXLEN;
118 else
119 block_read = todo;
120
121 if (w1_f2d_readblock(sl, off, block_read, buf) < 0)
122 count = -EIO;
123
124 todo -= W1_F2D_READ_MAXLEN;
125 buf += W1_F2D_READ_MAXLEN;
126 off += W1_F2D_READ_MAXLEN;
127 }
128
129 mutex_unlock(&sl->master->mutex);
130
131 return count;
132}
133
134/*
135 * Writes to the scratchpad and reads it back for verification.
136 * Then copies the scratchpad to EEPROM.
137 * The data must be aligned at W1_F2D_SCRATCH_SIZE bytes and
138 * must be W1_F2D_SCRATCH_SIZE bytes long.
139 * The master must be locked.
140 *
141 * @param sl The slave structure
142 * @param addr Address for the write
143 * @param len length must be <= (W1_F2D_PAGE_SIZE - (addr & W1_F2D_PAGE_MASK))
144 * @param data The data to write
145 * @return 0=Success -1=failure
146 */
147static int w1_f2d_write(struct w1_slave *sl, int addr, int len, const u8 *data)
148{
149 int tries = W1_F2D_READ_RETRIES;
150 u8 wrbuf[4];
151 u8 rdbuf[W1_F2D_SCRATCH_SIZE + 3];
152 u8 es = (addr + len - 1) % W1_F2D_SCRATCH_SIZE;
153
154retry:
155
156 /* Write the data to the scratchpad */
157 if (w1_reset_select_slave(sl))
158 return -1;
159
160 wrbuf[0] = W1_F2D_WRITE_SCRATCH;
161 wrbuf[1] = addr & 0xff;
162 wrbuf[2] = addr >> 8;
163
164 w1_write_block(sl->master, wrbuf, 3);
165 w1_write_block(sl->master, data, len);
166
167 /* Read the scratchpad and verify */
168 if (w1_reset_select_slave(sl))
169 return -1;
170
171 w1_write_8(sl->master, W1_F2D_READ_SCRATCH);
172 w1_read_block(sl->master, rdbuf, len + 3);
173
174 /* Compare what was read against the data written */
175 if ((rdbuf[0] != wrbuf[1]) || (rdbuf[1] != wrbuf[2]) ||
176 (rdbuf[2] != es) || (memcmp(data, &rdbuf[3], len) != 0)) {
177
178 if (--tries)
179 goto retry;
180
181 dev_err(&sl->dev,
182 "could not write to eeprom, scratchpad compare failed %d times\n",
183 W1_F2D_READ_RETRIES);
184
185 return -1;
186 }
187
188 /* Copy the scratchpad to EEPROM */
189 if (w1_reset_select_slave(sl))
190 return -1;
191
192 wrbuf[0] = W1_F2D_COPY_SCRATCH;
193 wrbuf[3] = es;
194 w1_write_block(sl->master, wrbuf, 4);
195
196 /* Sleep for tprog ms to wait for the write to complete */
197 msleep(W1_F2D_TPROG_MS);
198
199 /* Reset the bus to wake up the EEPROM */
200 w1_reset_bus(sl->master);
201
202 return 0;
203}
204
205static ssize_t w1_f2d_write_bin(struct kobject *kobj,
206 struct bin_attribute *bin_attr,
207 char *buf, loff_t off, size_t count)
208{
209 struct w1_slave *sl = kobj_to_w1_slave(kobj);
210 int addr, len;
211 int copy;
212
213 count = w1_f2d_fix_count(off, count, W1_F2D_EEPROM_SIZE);
214 if (count == 0)
215 return 0;
216
217 mutex_lock(&sl->master->mutex);
218
219 /* Can only write data in blocks of the size of the scratchpad */
220 addr = off;
221 len = count;
222 while (len > 0) {
223
224 /* if len too short or addr not aligned */
225 if (len < W1_F2D_SCRATCH_SIZE || addr & W1_F2D_SCRATCH_MASK) {
226 char tmp[W1_F2D_SCRATCH_SIZE];
227
228 /* read the block and update the parts to be written */
229 if (w1_f2d_readblock(sl, addr & ~W1_F2D_SCRATCH_MASK,
230 W1_F2D_SCRATCH_SIZE, tmp)) {
231 count = -EIO;
232 goto out_up;
233 }
234
235 /* copy at most to the boundary of the PAGE or len */
236 copy = W1_F2D_SCRATCH_SIZE -
237 (addr & W1_F2D_SCRATCH_MASK);
238
239 if (copy > len)
240 copy = len;
241
242 memcpy(&tmp[addr & W1_F2D_SCRATCH_MASK], buf, copy);
243 if (w1_f2d_write(sl, addr & ~W1_F2D_SCRATCH_MASK,
244 W1_F2D_SCRATCH_SIZE, tmp) < 0) {
245 count = -EIO;
246 goto out_up;
247 }
248 } else {
249
250 copy = W1_F2D_SCRATCH_SIZE;
251 if (w1_f2d_write(sl, addr, copy, buf) < 0) {
252 count = -EIO;
253 goto out_up;
254 }
255 }
256 buf += copy;
257 addr += copy;
258 len -= copy;
259 }
260
261out_up:
262 mutex_unlock(&sl->master->mutex);
263
264 return count;
265}
266
267static struct bin_attribute w1_f2d_bin_attr = {
268 .attr = {
269 .name = "eeprom",
270 .mode = S_IRUGO | S_IWUSR,
271 },
272 .size = W1_F2D_EEPROM_SIZE,
273 .read = w1_f2d_read_bin,
274 .write = w1_f2d_write_bin,
275};
276
277static int w1_f2d_add_slave(struct w1_slave *sl)
278{
279 return sysfs_create_bin_file(&sl->dev.kobj, &w1_f2d_bin_attr);
280}
281
282static void w1_f2d_remove_slave(struct w1_slave *sl)
283{
284 sysfs_remove_bin_file(&sl->dev.kobj, &w1_f2d_bin_attr);
285}
286
287static struct w1_family_ops w1_f2d_fops = {
288 .add_slave = w1_f2d_add_slave,
289 .remove_slave = w1_f2d_remove_slave,
290};
291
292static struct w1_family w1_family_2d = {
293 .fid = W1_EEPROM_DS2431,
294 .fops = &w1_f2d_fops,
295};
296
297static int __init w1_f2d_init(void)
298{
299 return w1_register_family(&w1_family_2d);
300}
301
302static void __exit w1_f2d_fini(void)
303{
304 w1_unregister_family(&w1_family_2d);
305}
306
307module_init(w1_f2d_init);
308module_exit(w1_f2d_fini);
309
310MODULE_LICENSE("GPL");
311MODULE_AUTHOR("Bernhard Weirich <bernhard.weirich@riedel.net>");
312MODULE_DESCRIPTION("w1 family 2d driver for DS2431, 1kb EEPROM");
diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c
index fb28acaeed6c..2c8dff9f77da 100644
--- a/drivers/w1/slaves/w1_therm.c
+++ b/drivers/w1/slaves/w1_therm.c
@@ -37,31 +37,33 @@ MODULE_LICENSE("GPL");
37MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>"); 37MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>");
38MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol, temperature family."); 38MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol, temperature family.");
39 39
40/* Allow the strong pullup to be disabled, but default to enabled.
41 * If it was disabled a parasite powered device might not get the require
42 * current to do a temperature conversion. If it is enabled parasite powered
43 * devices have a better chance of getting the current required.
44 */
45static int w1_strong_pullup = 1;
46module_param_named(strong_pullup, w1_strong_pullup, int, 0);
47
40static u8 bad_roms[][9] = { 48static u8 bad_roms[][9] = {
41 {0xaa, 0x00, 0x4b, 0x46, 0xff, 0xff, 0x0c, 0x10, 0x87}, 49 {0xaa, 0x00, 0x4b, 0x46, 0xff, 0xff, 0x0c, 0x10, 0x87},
42 {} 50 {}
43 }; 51 };
44 52
45static ssize_t w1_therm_read_bin(struct kobject *, struct bin_attribute *, 53static ssize_t w1_therm_read(struct device *device,
46 char *, loff_t, size_t); 54 struct device_attribute *attr, char *buf);
47 55
48static struct bin_attribute w1_therm_bin_attr = { 56static struct device_attribute w1_therm_attr =
49 .attr = { 57 __ATTR(w1_slave, S_IRUGO, w1_therm_read, NULL);
50 .name = "w1_slave",
51 .mode = S_IRUGO,
52 },
53 .size = W1_SLAVE_DATA_SIZE,
54 .read = w1_therm_read_bin,
55};
56 58
57static int w1_therm_add_slave(struct w1_slave *sl) 59static int w1_therm_add_slave(struct w1_slave *sl)
58{ 60{
59 return sysfs_create_bin_file(&sl->dev.kobj, &w1_therm_bin_attr); 61 return device_create_file(&sl->dev, &w1_therm_attr);
60} 62}
61 63
62static void w1_therm_remove_slave(struct w1_slave *sl) 64static void w1_therm_remove_slave(struct w1_slave *sl)
63{ 65{
64 sysfs_remove_bin_file(&sl->dev.kobj, &w1_therm_bin_attr); 66 device_remove_file(&sl->dev, &w1_therm_attr);
65} 67}
66 68
67static struct w1_family_ops w1_therm_fops = { 69static struct w1_family_ops w1_therm_fops = {
@@ -160,30 +162,19 @@ static int w1_therm_check_rom(u8 rom[9])
160 return 0; 162 return 0;
161} 163}
162 164
163static ssize_t w1_therm_read_bin(struct kobject *kobj, 165static ssize_t w1_therm_read(struct device *device,
164 struct bin_attribute *bin_attr, 166 struct device_attribute *attr, char *buf)
165 char *buf, loff_t off, size_t count)
166{ 167{
167 struct w1_slave *sl = kobj_to_w1_slave(kobj); 168 struct w1_slave *sl = dev_to_w1_slave(device);
168 struct w1_master *dev = sl->master; 169 struct w1_master *dev = sl->master;
169 u8 rom[9], crc, verdict; 170 u8 rom[9], crc, verdict;
170 int i, max_trying = 10; 171 int i, max_trying = 10;
172 ssize_t c = PAGE_SIZE;
171 173
172 mutex_lock(&sl->master->mutex); 174 mutex_lock(&dev->mutex);
173 175
174 if (off > W1_SLAVE_DATA_SIZE) {
175 count = 0;
176 goto out;
177 }
178 if (off + count > W1_SLAVE_DATA_SIZE) {
179 count = 0;
180 goto out;
181 }
182
183 memset(buf, 0, count);
184 memset(rom, 0, sizeof(rom)); 176 memset(rom, 0, sizeof(rom));
185 177
186 count = 0;
187 verdict = 0; 178 verdict = 0;
188 crc = 0; 179 crc = 0;
189 180
@@ -192,15 +183,20 @@ static ssize_t w1_therm_read_bin(struct kobject *kobj,
192 int count = 0; 183 int count = 0;
193 unsigned int tm = 750; 184 unsigned int tm = 750;
194 185
186 /* 750ms strong pullup (or delay) after the convert */
187 if (w1_strong_pullup)
188 w1_next_pullup(dev, tm);
195 w1_write_8(dev, W1_CONVERT_TEMP); 189 w1_write_8(dev, W1_CONVERT_TEMP);
196 190 if (!w1_strong_pullup)
197 msleep(tm); 191 msleep(tm);
198 192
199 if (!w1_reset_select_slave(sl)) { 193 if (!w1_reset_select_slave(sl)) {
200 194
201 w1_write_8(dev, W1_READ_SCRATCHPAD); 195 w1_write_8(dev, W1_READ_SCRATCHPAD);
202 if ((count = w1_read_block(dev, rom, 9)) != 9) { 196 if ((count = w1_read_block(dev, rom, 9)) != 9) {
203 dev_warn(&dev->dev, "w1_read_block() returned %d instead of 9.\n", count); 197 dev_warn(device, "w1_read_block() "
198 "returned %u instead of 9.\n",
199 count);
204 } 200 }
205 201
206 crc = w1_calc_crc8(rom, 8); 202 crc = w1_calc_crc8(rom, 8);
@@ -215,22 +211,22 @@ static ssize_t w1_therm_read_bin(struct kobject *kobj,
215 } 211 }
216 212
217 for (i = 0; i < 9; ++i) 213 for (i = 0; i < 9; ++i)
218 count += sprintf(buf + count, "%02x ", rom[i]); 214 c -= snprintf(buf + PAGE_SIZE - c, c, "%02x ", rom[i]);
219 count += sprintf(buf + count, ": crc=%02x %s\n", 215 c -= snprintf(buf + PAGE_SIZE - c, c, ": crc=%02x %s\n",
220 crc, (verdict) ? "YES" : "NO"); 216 crc, (verdict) ? "YES" : "NO");
221 if (verdict) 217 if (verdict)
222 memcpy(sl->rom, rom, sizeof(sl->rom)); 218 memcpy(sl->rom, rom, sizeof(sl->rom));
223 else 219 else
224 dev_warn(&dev->dev, "18S20 doesn't respond to CONVERT_TEMP.\n"); 220 dev_warn(device, "18S20 doesn't respond to CONVERT_TEMP.\n");
225 221
226 for (i = 0; i < 9; ++i) 222 for (i = 0; i < 9; ++i)
227 count += sprintf(buf + count, "%02x ", sl->rom[i]); 223 c -= snprintf(buf + PAGE_SIZE - c, c, "%02x ", sl->rom[i]);
228 224
229 count += sprintf(buf + count, "t=%d\n", w1_convert_temp(rom, sl->family->fid)); 225 c -= snprintf(buf + PAGE_SIZE - c, c, "t=%d\n",
230out: 226 w1_convert_temp(rom, sl->family->fid));
231 mutex_unlock(&dev->mutex); 227 mutex_unlock(&dev->mutex);
232 228
233 return count; 229 return PAGE_SIZE - c;
234} 230}
235 231
236static int __init w1_therm_init(void) 232static int __init w1_therm_init(void)
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index 7293c9b11f91..3b615d4022ee 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -46,19 +46,17 @@ MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>");
46MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol."); 46MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol.");
47 47
48static int w1_timeout = 10; 48static int w1_timeout = 10;
49static int w1_control_timeout = 1;
50int w1_max_slave_count = 10; 49int w1_max_slave_count = 10;
51int w1_max_slave_ttl = 10; 50int w1_max_slave_ttl = 10;
52 51
53module_param_named(timeout, w1_timeout, int, 0); 52module_param_named(timeout, w1_timeout, int, 0);
54module_param_named(control_timeout, w1_control_timeout, int, 0);
55module_param_named(max_slave_count, w1_max_slave_count, int, 0); 53module_param_named(max_slave_count, w1_max_slave_count, int, 0);
56module_param_named(slave_ttl, w1_max_slave_ttl, int, 0); 54module_param_named(slave_ttl, w1_max_slave_ttl, int, 0);
57 55
58DEFINE_MUTEX(w1_mlock); 56DEFINE_MUTEX(w1_mlock);
59LIST_HEAD(w1_masters); 57LIST_HEAD(w1_masters);
60 58
61static struct task_struct *w1_control_thread; 59static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn);
62 60
63static int w1_master_match(struct device *dev, struct device_driver *drv) 61static int w1_master_match(struct device *dev, struct device_driver *drv)
64{ 62{
@@ -83,10 +81,10 @@ static void w1_slave_release(struct device *dev)
83{ 81{
84 struct w1_slave *sl = dev_to_w1_slave(dev); 82 struct w1_slave *sl = dev_to_w1_slave(dev);
85 83
86 printk("%s: Releasing %s.\n", __func__, sl->name); 84 dev_dbg(dev, "%s: Releasing %s.\n", __func__, sl->name);
87 85
88 while (atomic_read(&sl->refcnt)) { 86 while (atomic_read(&sl->refcnt)) {
89 printk("Waiting for %s to become free: refcnt=%d.\n", 87 dev_dbg(dev, "Waiting for %s to become free: refcnt=%d.\n",
90 sl->name, atomic_read(&sl->refcnt)); 88 sl->name, atomic_read(&sl->refcnt));
91 if (msleep_interruptible(1000)) 89 if (msleep_interruptible(1000))
92 flush_signals(current); 90 flush_signals(current);
@@ -105,35 +103,20 @@ static ssize_t w1_slave_read_name(struct device *dev, struct device_attribute *a
105 return sprintf(buf, "%s\n", sl->name); 103 return sprintf(buf, "%s\n", sl->name);
106} 104}
107 105
108static ssize_t w1_slave_read_id(struct kobject *kobj, 106static ssize_t w1_slave_read_id(struct device *dev,
109 struct bin_attribute *bin_attr, 107 struct device_attribute *attr, char *buf)
110 char *buf, loff_t off, size_t count)
111{ 108{
112 struct w1_slave *sl = kobj_to_w1_slave(kobj); 109 struct w1_slave *sl = dev_to_w1_slave(dev);
113 110 ssize_t count = sizeof(sl->reg_num);
114 if (off > 8) {
115 count = 0;
116 } else {
117 if (off + count > 8)
118 count = 8 - off;
119
120 memcpy(buf, (u8 *)&sl->reg_num, count);
121 }
122 111
112 memcpy(buf, (u8 *)&sl->reg_num, count);
123 return count; 113 return count;
124} 114}
125 115
126static struct device_attribute w1_slave_attr_name = 116static struct device_attribute w1_slave_attr_name =
127 __ATTR(name, S_IRUGO, w1_slave_read_name, NULL); 117 __ATTR(name, S_IRUGO, w1_slave_read_name, NULL);
128 118static struct device_attribute w1_slave_attr_id =
129static struct bin_attribute w1_slave_attr_bin_id = { 119 __ATTR(id, S_IRUGO, w1_slave_read_id, NULL);
130 .attr = {
131 .name = "id",
132 .mode = S_IRUGO,
133 },
134 .size = 8,
135 .read = w1_slave_read_id,
136};
137 120
138/* Default family */ 121/* Default family */
139 122
@@ -250,11 +233,16 @@ static ssize_t w1_master_attribute_store_search(struct device * dev,
250 struct device_attribute *attr, 233 struct device_attribute *attr,
251 const char * buf, size_t count) 234 const char * buf, size_t count)
252{ 235{
236 long tmp;
253 struct w1_master *md = dev_to_w1_master(dev); 237 struct w1_master *md = dev_to_w1_master(dev);
254 238
239 if (strict_strtol(buf, 0, &tmp) == -EINVAL)
240 return -EINVAL;
241
255 mutex_lock(&md->mutex); 242 mutex_lock(&md->mutex);
256 md->search_count = simple_strtol(buf, NULL, 0); 243 md->search_count = tmp;
257 mutex_unlock(&md->mutex); 244 mutex_unlock(&md->mutex);
245 wake_up_process(md->thread);
258 246
259 return count; 247 return count;
260} 248}
@@ -273,6 +261,38 @@ static ssize_t w1_master_attribute_show_search(struct device *dev,
273 return count; 261 return count;
274} 262}
275 263
264static ssize_t w1_master_attribute_store_pullup(struct device *dev,
265 struct device_attribute *attr,
266 const char *buf, size_t count)
267{
268 long tmp;
269 struct w1_master *md = dev_to_w1_master(dev);
270
271 if (strict_strtol(buf, 0, &tmp) == -EINVAL)
272 return -EINVAL;
273
274 mutex_lock(&md->mutex);
275 md->enable_pullup = tmp;
276 mutex_unlock(&md->mutex);
277 wake_up_process(md->thread);
278
279 return count;
280}
281
282static ssize_t w1_master_attribute_show_pullup(struct device *dev,
283 struct device_attribute *attr,
284 char *buf)
285{
286 struct w1_master *md = dev_to_w1_master(dev);
287 ssize_t count;
288
289 mutex_lock(&md->mutex);
290 count = sprintf(buf, "%d\n", md->enable_pullup);
291 mutex_unlock(&md->mutex);
292
293 return count;
294}
295
276static ssize_t w1_master_attribute_show_pointer(struct device *dev, struct device_attribute *attr, char *buf) 296static ssize_t w1_master_attribute_show_pointer(struct device *dev, struct device_attribute *attr, char *buf)
277{ 297{
278 struct w1_master *md = dev_to_w1_master(dev); 298 struct w1_master *md = dev_to_w1_master(dev);
@@ -324,7 +344,8 @@ static ssize_t w1_master_attribute_show_slave_count(struct device *dev, struct d
324 return count; 344 return count;
325} 345}
326 346
327static ssize_t w1_master_attribute_show_slaves(struct device *dev, struct device_attribute *attr, char *buf) 347static ssize_t w1_master_attribute_show_slaves(struct device *dev,
348 struct device_attribute *attr, char *buf)
328{ 349{
329 struct w1_master *md = dev_to_w1_master(dev); 350 struct w1_master *md = dev_to_w1_master(dev);
330 int c = PAGE_SIZE; 351 int c = PAGE_SIZE;
@@ -349,6 +370,135 @@ static ssize_t w1_master_attribute_show_slaves(struct device *dev, struct device
349 return PAGE_SIZE - c; 370 return PAGE_SIZE - c;
350} 371}
351 372
373static ssize_t w1_master_attribute_show_add(struct device *dev,
374 struct device_attribute *attr, char *buf)
375{
376 int c = PAGE_SIZE;
377 c -= snprintf(buf+PAGE_SIZE - c, c,
378 "write device id xx-xxxxxxxxxxxx to add slave\n");
379 return PAGE_SIZE - c;
380}
381
382static int w1_atoreg_num(struct device *dev, const char *buf, size_t count,
383 struct w1_reg_num *rn)
384{
385 unsigned int family;
386 unsigned long long id;
387 int i;
388 u64 rn64_le;
389
390 /* The CRC value isn't read from the user because the sysfs directory
391 * doesn't include it and most messages from the bus search don't
392 * print it either. It would be unreasonable for the user to then
393 * provide it.
394 */
395 const char *error_msg = "bad slave string format, expecting "
396 "ff-dddddddddddd\n";
397
398 if (buf[2] != '-') {
399 dev_err(dev, "%s", error_msg);
400 return -EINVAL;
401 }
402 i = sscanf(buf, "%02x-%012llx", &family, &id);
403 if (i != 2) {
404 dev_err(dev, "%s", error_msg);
405 return -EINVAL;
406 }
407 rn->family = family;
408 rn->id = id;
409
410 rn64_le = cpu_to_le64(*(u64 *)rn);
411 rn->crc = w1_calc_crc8((u8 *)&rn64_le, 7);
412
413#if 0
414 dev_info(dev, "With CRC device is %02x.%012llx.%02x.\n",
415 rn->family, (unsigned long long)rn->id, rn->crc);
416#endif
417
418 return 0;
419}
420
421/* Searches the slaves in the w1_master and returns a pointer or NULL.
422 * Note: must hold the mutex
423 */
424static struct w1_slave *w1_slave_search_device(struct w1_master *dev,
425 struct w1_reg_num *rn)
426{
427 struct w1_slave *sl;
428 list_for_each_entry(sl, &dev->slist, w1_slave_entry) {
429 if (sl->reg_num.family == rn->family &&
430 sl->reg_num.id == rn->id &&
431 sl->reg_num.crc == rn->crc) {
432 return sl;
433 }
434 }
435 return NULL;
436}
437
438static ssize_t w1_master_attribute_store_add(struct device *dev,
439 struct device_attribute *attr,
440 const char *buf, size_t count)
441{
442 struct w1_master *md = dev_to_w1_master(dev);
443 struct w1_reg_num rn;
444 struct w1_slave *sl;
445 ssize_t result = count;
446
447 if (w1_atoreg_num(dev, buf, count, &rn))
448 return -EINVAL;
449
450 mutex_lock(&md->mutex);
451 sl = w1_slave_search_device(md, &rn);
452 /* It would be nice to do a targeted search one the one-wire bus
453 * for the new device to see if it is out there or not. But the
454 * current search doesn't support that.
455 */
456 if (sl) {
457 dev_info(dev, "Device %s already exists\n", sl->name);
458 result = -EINVAL;
459 } else {
460 w1_attach_slave_device(md, &rn);
461 }
462 mutex_unlock(&md->mutex);
463
464 return result;
465}
466
467static ssize_t w1_master_attribute_show_remove(struct device *dev,
468 struct device_attribute *attr, char *buf)
469{
470 int c = PAGE_SIZE;
471 c -= snprintf(buf+PAGE_SIZE - c, c,
472 "write device id xx-xxxxxxxxxxxx to remove slave\n");
473 return PAGE_SIZE - c;
474}
475
476static ssize_t w1_master_attribute_store_remove(struct device *dev,
477 struct device_attribute *attr,
478 const char *buf, size_t count)
479{
480 struct w1_master *md = dev_to_w1_master(dev);
481 struct w1_reg_num rn;
482 struct w1_slave *sl;
483 ssize_t result = count;
484
485 if (w1_atoreg_num(dev, buf, count, &rn))
486 return -EINVAL;
487
488 mutex_lock(&md->mutex);
489 sl = w1_slave_search_device(md, &rn);
490 if (sl) {
491 w1_slave_detach(sl);
492 } else {
493 dev_info(dev, "Device %02x-%012llx doesn't exists\n", rn.family,
494 (unsigned long long)rn.id);
495 result = -EINVAL;
496 }
497 mutex_unlock(&md->mutex);
498
499 return result;
500}
501
352#define W1_MASTER_ATTR_RO(_name, _mode) \ 502#define W1_MASTER_ATTR_RO(_name, _mode) \
353 struct device_attribute w1_master_attribute_##_name = \ 503 struct device_attribute w1_master_attribute_##_name = \
354 __ATTR(w1_master_##_name, _mode, \ 504 __ATTR(w1_master_##_name, _mode, \
@@ -368,6 +518,9 @@ static W1_MASTER_ATTR_RO(attempts, S_IRUGO);
368static W1_MASTER_ATTR_RO(timeout, S_IRUGO); 518static W1_MASTER_ATTR_RO(timeout, S_IRUGO);
369static W1_MASTER_ATTR_RO(pointer, S_IRUGO); 519static W1_MASTER_ATTR_RO(pointer, S_IRUGO);
370static W1_MASTER_ATTR_RW(search, S_IRUGO | S_IWUGO); 520static W1_MASTER_ATTR_RW(search, S_IRUGO | S_IWUGO);
521static W1_MASTER_ATTR_RW(pullup, S_IRUGO | S_IWUGO);
522static W1_MASTER_ATTR_RW(add, S_IRUGO | S_IWUGO);
523static W1_MASTER_ATTR_RW(remove, S_IRUGO | S_IWUGO);
371 524
372static struct attribute *w1_master_default_attrs[] = { 525static struct attribute *w1_master_default_attrs[] = {
373 &w1_master_attribute_name.attr, 526 &w1_master_attribute_name.attr,
@@ -378,6 +531,9 @@ static struct attribute *w1_master_default_attrs[] = {
378 &w1_master_attribute_timeout.attr, 531 &w1_master_attribute_timeout.attr,
379 &w1_master_attribute_pointer.attr, 532 &w1_master_attribute_pointer.attr,
380 &w1_master_attribute_search.attr, 533 &w1_master_attribute_search.attr,
534 &w1_master_attribute_pullup.attr,
535 &w1_master_attribute_add.attr,
536 &w1_master_attribute_remove.attr,
381 NULL 537 NULL
382}; 538};
383 539
@@ -390,7 +546,7 @@ int w1_create_master_attributes(struct w1_master *master)
390 return sysfs_create_group(&master->dev.kobj, &w1_master_defattr_group); 546 return sysfs_create_group(&master->dev.kobj, &w1_master_defattr_group);
391} 547}
392 548
393static void w1_destroy_master_attributes(struct w1_master *master) 549void w1_destroy_master_attributes(struct w1_master *master)
394{ 550{
395 sysfs_remove_group(&master->dev.kobj, &w1_master_defattr_group); 551 sysfs_remove_group(&master->dev.kobj, &w1_master_defattr_group);
396} 552}
@@ -479,7 +635,7 @@ static int __w1_attach_slave_device(struct w1_slave *sl)
479 } 635 }
480 636
481 /* Create "id" entry */ 637 /* Create "id" entry */
482 err = sysfs_create_bin_file(&sl->dev.kobj, &w1_slave_attr_bin_id); 638 err = device_create_file(&sl->dev, &w1_slave_attr_id);
483 if (err < 0) { 639 if (err < 0) {
484 dev_err(&sl->dev, 640 dev_err(&sl->dev,
485 "sysfs file creation for [%s] failed. err=%d\n", 641 "sysfs file creation for [%s] failed. err=%d\n",
@@ -501,7 +657,7 @@ static int __w1_attach_slave_device(struct w1_slave *sl)
501 return 0; 657 return 0;
502 658
503out_rem2: 659out_rem2:
504 sysfs_remove_bin_file(&sl->dev.kobj, &w1_slave_attr_bin_id); 660 device_remove_file(&sl->dev, &w1_slave_attr_id);
505out_rem1: 661out_rem1:
506 device_remove_file(&sl->dev, &w1_slave_attr_name); 662 device_remove_file(&sl->dev, &w1_slave_attr_name);
507out_unreg: 663out_unreg:
@@ -567,7 +723,7 @@ static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn)
567 return 0; 723 return 0;
568} 724}
569 725
570static void w1_slave_detach(struct w1_slave *sl) 726void w1_slave_detach(struct w1_slave *sl)
571{ 727{
572 struct w1_netlink_msg msg; 728 struct w1_netlink_msg msg;
573 729
@@ -583,7 +739,7 @@ static void w1_slave_detach(struct w1_slave *sl)
583 msg.type = W1_SLAVE_REMOVE; 739 msg.type = W1_SLAVE_REMOVE;
584 w1_netlink_send(sl->master, &msg); 740 w1_netlink_send(sl->master, &msg);
585 741
586 sysfs_remove_bin_file(&sl->dev.kobj, &w1_slave_attr_bin_id); 742 device_remove_file(&sl->dev, &w1_slave_attr_id);
587 device_remove_file(&sl->dev, &w1_slave_attr_name); 743 device_remove_file(&sl->dev, &w1_slave_attr_name);
588 device_unregister(&sl->dev); 744 device_unregister(&sl->dev);
589 745
@@ -591,24 +747,6 @@ static void w1_slave_detach(struct w1_slave *sl)
591 kfree(sl); 747 kfree(sl);
592} 748}
593 749
594static struct w1_master *w1_search_master(void *data)
595{
596 struct w1_master *dev;
597 int found = 0;
598
599 mutex_lock(&w1_mlock);
600 list_for_each_entry(dev, &w1_masters, w1_master_entry) {
601 if (dev->bus_master->data == data) {
602 found = 1;
603 atomic_inc(&dev->refcnt);
604 break;
605 }
606 }
607 mutex_unlock(&w1_mlock);
608
609 return (found)?dev:NULL;
610}
611
612struct w1_master *w1_search_master_id(u32 id) 750struct w1_master *w1_search_master_id(u32 id)
613{ 751{
614 struct w1_master *dev; 752 struct w1_master *dev;
@@ -656,55 +794,56 @@ struct w1_slave *w1_search_slave(struct w1_reg_num *id)
656 return (found)?sl:NULL; 794 return (found)?sl:NULL;
657} 795}
658 796
659void w1_reconnect_slaves(struct w1_family *f) 797void w1_reconnect_slaves(struct w1_family *f, int attach)
660{ 798{
799 struct w1_slave *sl, *sln;
661 struct w1_master *dev; 800 struct w1_master *dev;
662 801
663 mutex_lock(&w1_mlock); 802 mutex_lock(&w1_mlock);
664 list_for_each_entry(dev, &w1_masters, w1_master_entry) { 803 list_for_each_entry(dev, &w1_masters, w1_master_entry) {
665 dev_dbg(&dev->dev, "Reconnecting slaves in %s into new family %02x.\n", 804 dev_dbg(&dev->dev, "Reconnecting slaves in device %s "
666 dev->name, f->fid); 805 "for family %02x.\n", dev->name, f->fid);
667 set_bit(W1_MASTER_NEED_RECONNECT, &dev->flags); 806 mutex_lock(&dev->mutex);
807 list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) {
808 /* If it is a new family, slaves with the default
809 * family driver and are that family will be
810 * connected. If the family is going away, devices
811 * matching that family are reconneced.
812 */
813 if ((attach && sl->family->fid == W1_FAMILY_DEFAULT
814 && sl->reg_num.family == f->fid) ||
815 (!attach && sl->family->fid == f->fid)) {
816 struct w1_reg_num rn;
817
818 memcpy(&rn, &sl->reg_num, sizeof(rn));
819 w1_slave_detach(sl);
820
821 w1_attach_slave_device(dev, &rn);
822 }
823 }
824 dev_dbg(&dev->dev, "Reconnecting slaves in device %s "
825 "has been finished.\n", dev->name);
826 mutex_unlock(&dev->mutex);
668 } 827 }
669 mutex_unlock(&w1_mlock); 828 mutex_unlock(&w1_mlock);
670} 829}
671 830
672static void w1_slave_found(void *data, u64 rn) 831static void w1_slave_found(struct w1_master *dev, u64 rn)
673{ 832{
674 int slave_count;
675 struct w1_slave *sl; 833 struct w1_slave *sl;
676 struct list_head *ent;
677 struct w1_reg_num *tmp; 834 struct w1_reg_num *tmp;
678 struct w1_master *dev;
679 u64 rn_le = cpu_to_le64(rn); 835 u64 rn_le = cpu_to_le64(rn);
680 836
681 dev = w1_search_master(data); 837 atomic_inc(&dev->refcnt);
682 if (!dev) {
683 printk(KERN_ERR "Failed to find w1 master device for data %p, "
684 "it is impossible.\n", data);
685 return;
686 }
687 838
688 tmp = (struct w1_reg_num *) &rn; 839 tmp = (struct w1_reg_num *) &rn;
689 840
690 slave_count = 0; 841 sl = w1_slave_search_device(dev, tmp);
691 list_for_each(ent, &dev->slist) { 842 if (sl) {
692 843 set_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags);
693 sl = list_entry(ent, struct w1_slave, w1_slave_entry); 844 } else {
694 845 if (rn && tmp->crc == w1_calc_crc8((u8 *)&rn_le, 7))
695 if (sl->reg_num.family == tmp->family && 846 w1_attach_slave_device(dev, tmp);
696 sl->reg_num.id == tmp->id &&
697 sl->reg_num.crc == tmp->crc) {
698 set_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags);
699 break;
700 }
701
702 slave_count++;
703 }
704
705 if (slave_count == dev->slave_count &&
706 rn && ((rn >> 56) & 0xff) == w1_calc_crc8((u8 *)&rn_le, 7)) {
707 w1_attach_slave_device(dev, tmp);
708 } 847 }
709 848
710 atomic_dec(&dev->refcnt); 849 atomic_dec(&dev->refcnt);
@@ -779,80 +918,20 @@ void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb
779 /* extract the direction taken & update the device number */ 918 /* extract the direction taken & update the device number */
780 tmp64 = (triplet_ret >> 2); 919 tmp64 = (triplet_ret >> 2);
781 rn |= (tmp64 << i); 920 rn |= (tmp64 << i);
921
922 if (kthread_should_stop()) {
923 dev_dbg(&dev->dev, "Abort w1_search\n");
924 return;
925 }
782 } 926 }
783 927
784 if ( (triplet_ret & 0x03) != 0x03 ) { 928 if ( (triplet_ret & 0x03) != 0x03 ) {
785 if ( (desc_bit == last_zero) || (last_zero < 0)) 929 if ( (desc_bit == last_zero) || (last_zero < 0))
786 last_device = 1; 930 last_device = 1;
787 desc_bit = last_zero; 931 desc_bit = last_zero;
788 cb(dev->bus_master->data, rn); 932 cb(dev, rn);
789 }
790 }
791}
792
793static int w1_control(void *data)
794{
795 struct w1_slave *sl, *sln;
796 struct w1_master *dev, *n;
797 int have_to_wait = 0;
798
799 set_freezable();
800 while (!kthread_should_stop() || have_to_wait) {
801 have_to_wait = 0;
802
803 try_to_freeze();
804 msleep_interruptible(w1_control_timeout * 1000);
805
806 list_for_each_entry_safe(dev, n, &w1_masters, w1_master_entry) {
807 if (!kthread_should_stop() && !dev->flags)
808 continue;
809 /*
810 * Little race: we can create thread but not set the flag.
811 * Get a chance for external process to set flag up.
812 */
813 if (!dev->initialized) {
814 have_to_wait = 1;
815 continue;
816 }
817
818 if (kthread_should_stop() || test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) {
819 set_bit(W1_MASTER_NEED_EXIT, &dev->flags);
820
821 mutex_lock(&w1_mlock);
822 list_del(&dev->w1_master_entry);
823 mutex_unlock(&w1_mlock);
824
825 mutex_lock(&dev->mutex);
826 list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) {
827 w1_slave_detach(sl);
828 }
829 w1_destroy_master_attributes(dev);
830 mutex_unlock(&dev->mutex);
831 atomic_dec(&dev->refcnt);
832 continue;
833 }
834
835 if (test_bit(W1_MASTER_NEED_RECONNECT, &dev->flags)) {
836 dev_dbg(&dev->dev, "Reconnecting slaves in device %s.\n", dev->name);
837 mutex_lock(&dev->mutex);
838 list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) {
839 if (sl->family->fid == W1_FAMILY_DEFAULT) {
840 struct w1_reg_num rn;
841
842 memcpy(&rn, &sl->reg_num, sizeof(rn));
843 w1_slave_detach(sl);
844
845 w1_attach_slave_device(dev, &rn);
846 }
847 }
848 dev_dbg(&dev->dev, "Reconnecting slaves in device %s has been finished.\n", dev->name);
849 clear_bit(W1_MASTER_NEED_RECONNECT, &dev->flags);
850 mutex_unlock(&dev->mutex);
851 }
852 } 933 }
853 } 934 }
854
855 return 0;
856} 935}
857 936
858void w1_search_process(struct w1_master *dev, u8 search_type) 937void w1_search_process(struct w1_master *dev, u8 search_type)
@@ -878,23 +957,29 @@ void w1_search_process(struct w1_master *dev, u8 search_type)
878int w1_process(void *data) 957int w1_process(void *data)
879{ 958{
880 struct w1_master *dev = (struct w1_master *) data; 959 struct w1_master *dev = (struct w1_master *) data;
960 /* As long as w1_timeout is only set by a module parameter the sleep
961 * time can be calculated in jiffies once.
962 */
963 const unsigned long jtime = msecs_to_jiffies(w1_timeout * 1000);
964
965 while (!kthread_should_stop()) {
966 if (dev->search_count) {
967 mutex_lock(&dev->mutex);
968 w1_search_process(dev, W1_SEARCH);
969 mutex_unlock(&dev->mutex);
970 }
881 971
882 while (!kthread_should_stop() && !test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) {
883 try_to_freeze(); 972 try_to_freeze();
884 msleep_interruptible(w1_timeout * 1000); 973 __set_current_state(TASK_INTERRUPTIBLE);
885 974
886 if (kthread_should_stop() || test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) 975 if (kthread_should_stop())
887 break; 976 break;
888 977
889 if (!dev->initialized) 978 /* Only sleep when the search is active. */
890 continue; 979 if (dev->search_count)
891 980 schedule_timeout(jtime);
892 if (dev->search_count == 0) 981 else
893 continue; 982 schedule();
894
895 mutex_lock(&dev->mutex);
896 w1_search_process(dev, W1_SEARCH);
897 mutex_unlock(&dev->mutex);
898 } 983 }
899 984
900 atomic_dec(&dev->refcnt); 985 atomic_dec(&dev->refcnt);
@@ -932,18 +1017,13 @@ static int w1_init(void)
932 goto err_out_master_unregister; 1017 goto err_out_master_unregister;
933 } 1018 }
934 1019
935 w1_control_thread = kthread_run(w1_control, NULL, "w1_control");
936 if (IS_ERR(w1_control_thread)) {
937 retval = PTR_ERR(w1_control_thread);
938 printk(KERN_ERR "Failed to create control thread. err=%d\n",
939 retval);
940 goto err_out_slave_unregister;
941 }
942
943 return 0; 1020 return 0;
944 1021
1022#if 0
1023/* For undoing the slave register if there was a step after it. */
945err_out_slave_unregister: 1024err_out_slave_unregister:
946 driver_unregister(&w1_slave_driver); 1025 driver_unregister(&w1_slave_driver);
1026#endif
947 1027
948err_out_master_unregister: 1028err_out_master_unregister:
949 driver_unregister(&w1_master_driver); 1029 driver_unregister(&w1_master_driver);
@@ -959,13 +1039,12 @@ static void w1_fini(void)
959{ 1039{
960 struct w1_master *dev; 1040 struct w1_master *dev;
961 1041
1042 /* Set netlink removal messages and some cleanup */
962 list_for_each_entry(dev, &w1_masters, w1_master_entry) 1043 list_for_each_entry(dev, &w1_masters, w1_master_entry)
963 __w1_remove_master_device(dev); 1044 __w1_remove_master_device(dev);
964 1045
965 w1_fini_netlink(); 1046 w1_fini_netlink();
966 1047
967 kthread_stop(w1_control_thread);
968
969 driver_unregister(&w1_slave_driver); 1048 driver_unregister(&w1_slave_driver);
970 driver_unregister(&w1_master_driver); 1049 driver_unregister(&w1_master_driver);
971 bus_unregister(&w1_bus_type); 1050 bus_unregister(&w1_bus_type);
diff --git a/drivers/w1/w1.h b/drivers/w1/w1.h
index f1df5343f4ad..cdaa6fffbfc7 100644
--- a/drivers/w1/w1.h
+++ b/drivers/w1/w1.h
@@ -46,7 +46,6 @@ struct w1_reg_num
46#include "w1_family.h" 46#include "w1_family.h"
47 47
48#define W1_MAXNAMELEN 32 48#define W1_MAXNAMELEN 32
49#define W1_SLAVE_DATA_SIZE 128
50 49
51#define W1_SEARCH 0xF0 50#define W1_SEARCH 0xF0
52#define W1_ALARM_SEARCH 0xEC 51#define W1_ALARM_SEARCH 0xEC
@@ -77,7 +76,7 @@ struct w1_slave
77 struct completion released; 76 struct completion released;
78}; 77};
79 78
80typedef void (* w1_slave_found_callback)(void *, u64); 79typedef void (*w1_slave_found_callback)(struct w1_master *, u64);
81 80
82 81
83/** 82/**
@@ -142,12 +141,18 @@ struct w1_bus_master
142 */ 141 */
143 u8 (*reset_bus)(void *); 142 u8 (*reset_bus)(void *);
144 143
145 /** Really nice hardware can handles the different types of ROM search */ 144 /**
146 void (*search)(void *, u8, w1_slave_found_callback); 145 * Put out a strong pull-up pulse of the specified duration.
147}; 146 * @return -1=Error, 0=completed
147 */
148 u8 (*set_pullup)(void *, int);
148 149
149#define W1_MASTER_NEED_EXIT 0 150 /** Really nice hardware can handles the different types of ROM search
150#define W1_MASTER_NEED_RECONNECT 1 151 * w1_master* is passed to the slave found callback.
152 */
153 void (*search)(void *, struct w1_master *,
154 u8, w1_slave_found_callback);
155};
151 156
152struct w1_master 157struct w1_master
153{ 158{
@@ -167,7 +172,10 @@ struct w1_master
167 void *priv; 172 void *priv;
168 int priv_size; 173 int priv_size;
169 174
170 long flags; 175 /** 5V strong pullup enabled flag, 1 enabled, zero disabled. */
176 int enable_pullup;
177 /** 5V strong pullup duration in milliseconds, zero disabled. */
178 int pullup_duration;
171 179
172 struct task_struct *thread; 180 struct task_struct *thread;
173 struct mutex mutex; 181 struct mutex mutex;
@@ -181,12 +189,21 @@ struct w1_master
181}; 189};
182 190
183int w1_create_master_attributes(struct w1_master *); 191int w1_create_master_attributes(struct w1_master *);
192void w1_destroy_master_attributes(struct w1_master *master);
184void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb); 193void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb);
185void w1_search_devices(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb); 194void w1_search_devices(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb);
186struct w1_slave *w1_search_slave(struct w1_reg_num *id); 195struct w1_slave *w1_search_slave(struct w1_reg_num *id);
187void w1_search_process(struct w1_master *dev, u8 search_type); 196void w1_search_process(struct w1_master *dev, u8 search_type);
188struct w1_master *w1_search_master_id(u32 id); 197struct w1_master *w1_search_master_id(u32 id);
189 198
199/* Disconnect and reconnect devices in the given family. Used for finding
200 * unclaimed devices after a family has been registered or releasing devices
201 * after a family has been unregistered. Set attach to 1 when a new family
202 * has just been registered, to 0 when it has been unregistered.
203 */
204void w1_reconnect_slaves(struct w1_family *f, int attach);
205void w1_slave_detach(struct w1_slave *sl);
206
190u8 w1_triplet(struct w1_master *dev, int bdir); 207u8 w1_triplet(struct w1_master *dev, int bdir);
191void w1_write_8(struct w1_master *, u8); 208void w1_write_8(struct w1_master *, u8);
192int w1_reset_bus(struct w1_master *); 209int w1_reset_bus(struct w1_master *);
@@ -194,6 +211,7 @@ u8 w1_calc_crc8(u8 *, int);
194void w1_write_block(struct w1_master *, const u8 *, int); 211void w1_write_block(struct w1_master *, const u8 *, int);
195u8 w1_read_block(struct w1_master *, u8 *, int); 212u8 w1_read_block(struct w1_master *, u8 *, int);
196int w1_reset_select_slave(struct w1_slave *sl); 213int w1_reset_select_slave(struct w1_slave *sl);
214void w1_next_pullup(struct w1_master *, int);
197 215
198static inline struct w1_slave* dev_to_w1_slave(struct device *dev) 216static inline struct w1_slave* dev_to_w1_slave(struct device *dev)
199{ 217{
diff --git a/drivers/w1/w1_family.c b/drivers/w1/w1_family.c
index a3c95bd6890a..4a099041f28a 100644
--- a/drivers/w1/w1_family.c
+++ b/drivers/w1/w1_family.c
@@ -48,12 +48,12 @@ int w1_register_family(struct w1_family *newf)
48 48
49 if (!ret) { 49 if (!ret) {
50 atomic_set(&newf->refcnt, 0); 50 atomic_set(&newf->refcnt, 0);
51 newf->need_exit = 0;
52 list_add_tail(&newf->family_entry, &w1_families); 51 list_add_tail(&newf->family_entry, &w1_families);
53 } 52 }
54 spin_unlock(&w1_flock); 53 spin_unlock(&w1_flock);
55 54
56 w1_reconnect_slaves(newf); 55 /* check default devices against the new set of drivers */
56 w1_reconnect_slaves(newf, 1);
57 57
58 return ret; 58 return ret;
59} 59}
@@ -72,11 +72,11 @@ void w1_unregister_family(struct w1_family *fent)
72 break; 72 break;
73 } 73 }
74 } 74 }
75
76 fent->need_exit = 1;
77
78 spin_unlock(&w1_flock); 75 spin_unlock(&w1_flock);
79 76
77 /* deatch devices using this family code */
78 w1_reconnect_slaves(fent, 0);
79
80 while (atomic_read(&fent->refcnt)) { 80 while (atomic_read(&fent->refcnt)) {
81 printk(KERN_INFO "Waiting for family %u to become free: refcnt=%d.\n", 81 printk(KERN_INFO "Waiting for family %u to become free: refcnt=%d.\n",
82 fent->fid, atomic_read(&fent->refcnt)); 82 fent->fid, atomic_read(&fent->refcnt));
@@ -109,8 +109,7 @@ struct w1_family * w1_family_registered(u8 fid)
109 109
110static void __w1_family_put(struct w1_family *f) 110static void __w1_family_put(struct w1_family *f)
111{ 111{
112 if (atomic_dec_and_test(&f->refcnt)) 112 atomic_dec(&f->refcnt);
113 f->need_exit = 1;
114} 113}
115 114
116void w1_family_put(struct w1_family *f) 115void w1_family_put(struct w1_family *f)
diff --git a/drivers/w1/w1_family.h b/drivers/w1/w1_family.h
index ef1e1dafa19a..3ca1b9298f21 100644
--- a/drivers/w1/w1_family.h
+++ b/drivers/w1/w1_family.h
@@ -33,6 +33,7 @@
33#define W1_THERM_DS1822 0x22 33#define W1_THERM_DS1822 0x22
34#define W1_EEPROM_DS2433 0x23 34#define W1_EEPROM_DS2433 0x23
35#define W1_THERM_DS18B20 0x28 35#define W1_THERM_DS18B20 0x28
36#define W1_EEPROM_DS2431 0x2D
36#define W1_FAMILY_DS2760 0x30 37#define W1_FAMILY_DS2760 0x30
37 38
38#define MAXNAMELEN 32 39#define MAXNAMELEN 32
@@ -53,7 +54,6 @@ struct w1_family
53 struct w1_family_ops *fops; 54 struct w1_family_ops *fops;
54 55
55 atomic_t refcnt; 56 atomic_t refcnt;
56 u8 need_exit;
57}; 57};
58 58
59extern spinlock_t w1_flock; 59extern spinlock_t w1_flock;
@@ -63,6 +63,5 @@ void __w1_family_get(struct w1_family *);
63struct w1_family * w1_family_registered(u8); 63struct w1_family * w1_family_registered(u8);
64void w1_unregister_family(struct w1_family *); 64void w1_unregister_family(struct w1_family *);
65int w1_register_family(struct w1_family *); 65int w1_register_family(struct w1_family *);
66void w1_reconnect_slaves(struct w1_family *f);
67 66
68#endif /* __W1_FAMILY_H */ 67#endif /* __W1_FAMILY_H */
diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c
index 6840dfebe4d4..a3a54567bfba 100644
--- a/drivers/w1/w1_int.c
+++ b/drivers/w1/w1_int.c
@@ -29,7 +29,11 @@
29#include "w1_netlink.h" 29#include "w1_netlink.h"
30#include "w1_int.h" 30#include "w1_int.h"
31 31
32static u32 w1_ids = 1; 32static int w1_search_count = -1; /* Default is continual scan */
33module_param_named(search_count, w1_search_count, int, 0);
34
35static int w1_enable_pullup = 1;
36module_param_named(enable_pullup, w1_enable_pullup, int, 0);
33 37
34static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl, 38static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
35 struct device_driver *driver, 39 struct device_driver *driver,
@@ -59,8 +63,12 @@ static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
59 dev->initialized = 0; 63 dev->initialized = 0;
60 dev->id = id; 64 dev->id = id;
61 dev->slave_ttl = slave_ttl; 65 dev->slave_ttl = slave_ttl;
62 dev->search_count = -1; /* continual scan */ 66 dev->search_count = w1_search_count;
67 dev->enable_pullup = w1_enable_pullup;
63 68
69 /* 1 for w1_process to decrement
70 * 1 for __w1_remove_master_device to decrement
71 */
64 atomic_set(&dev->refcnt, 2); 72 atomic_set(&dev->refcnt, 2);
65 73
66 INIT_LIST_HEAD(&dev->slist); 74 INIT_LIST_HEAD(&dev->slist);
@@ -93,9 +101,10 @@ static void w1_free_dev(struct w1_master *dev)
93 101
94int w1_add_master_device(struct w1_bus_master *master) 102int w1_add_master_device(struct w1_bus_master *master)
95{ 103{
96 struct w1_master *dev; 104 struct w1_master *dev, *entry;
97 int retval = 0; 105 int retval = 0;
98 struct w1_netlink_msg msg; 106 struct w1_netlink_msg msg;
107 int id, found;
99 108
100 /* validate minimum functionality */ 109 /* validate minimum functionality */
101 if (!(master->touch_bit && master->reset_bus) && 110 if (!(master->touch_bit && master->reset_bus) &&
@@ -104,10 +113,50 @@ int w1_add_master_device(struct w1_bus_master *master)
104 printk(KERN_ERR "w1_add_master_device: invalid function set\n"); 113 printk(KERN_ERR "w1_add_master_device: invalid function set\n");
105 return(-EINVAL); 114 return(-EINVAL);
106 } 115 }
116 /* While it would be electrically possible to make a device that
117 * generated a strong pullup in bit bang mode, only hardare that
118 * controls 1-wire time frames are even expected to support a strong
119 * pullup. w1_io.c would need to support calling set_pullup before
120 * the last write_bit operation of a w1_write_8 which it currently
121 * doesn't.
122 */
123 if (!master->write_byte && !master->touch_bit && master->set_pullup) {
124 printk(KERN_ERR "w1_add_master_device: set_pullup requires "
125 "write_byte or touch_bit, disabling\n");
126 master->set_pullup = NULL;
127 }
128
129 /* Lock until the device is added (or not) to w1_masters. */
130 mutex_lock(&w1_mlock);
131 /* Search for the first available id (starting at 1). */
132 id = 0;
133 do {
134 ++id;
135 found = 0;
136 list_for_each_entry(entry, &w1_masters, w1_master_entry) {
137 if (entry->id == id) {
138 found = 1;
139 break;
140 }
141 }
142 } while (found);
107 143
108 dev = w1_alloc_dev(w1_ids++, w1_max_slave_count, w1_max_slave_ttl, &w1_master_driver, &w1_master_device); 144 dev = w1_alloc_dev(id, w1_max_slave_count, w1_max_slave_ttl,
109 if (!dev) 145 &w1_master_driver, &w1_master_device);
146 if (!dev) {
147 mutex_unlock(&w1_mlock);
110 return -ENOMEM; 148 return -ENOMEM;
149 }
150
151 retval = w1_create_master_attributes(dev);
152 if (retval) {
153 mutex_unlock(&w1_mlock);
154 goto err_out_free_dev;
155 }
156
157 memcpy(dev->bus_master, master, sizeof(struct w1_bus_master));
158
159 dev->initialized = 1;
111 160
112 dev->thread = kthread_run(&w1_process, dev, "%s", dev->name); 161 dev->thread = kthread_run(&w1_process, dev, "%s", dev->name);
113 if (IS_ERR(dev->thread)) { 162 if (IS_ERR(dev->thread)) {
@@ -115,18 +164,10 @@ int w1_add_master_device(struct w1_bus_master *master)
115 dev_err(&dev->dev, 164 dev_err(&dev->dev,
116 "Failed to create new kernel thread. err=%d\n", 165 "Failed to create new kernel thread. err=%d\n",
117 retval); 166 retval);
118 goto err_out_free_dev; 167 mutex_unlock(&w1_mlock);
168 goto err_out_rm_attr;
119 } 169 }
120 170
121 retval = w1_create_master_attributes(dev);
122 if (retval)
123 goto err_out_kill_thread;
124
125 memcpy(dev->bus_master, master, sizeof(struct w1_bus_master));
126
127 dev->initialized = 1;
128
129 mutex_lock(&w1_mlock);
130 list_add(&dev->w1_master_entry, &w1_masters); 171 list_add(&dev->w1_master_entry, &w1_masters);
131 mutex_unlock(&w1_mlock); 172 mutex_unlock(&w1_mlock);
132 173
@@ -137,8 +178,12 @@ int w1_add_master_device(struct w1_bus_master *master)
137 178
138 return 0; 179 return 0;
139 180
181#if 0 /* Thread cleanup code, not required currently. */
140err_out_kill_thread: 182err_out_kill_thread:
141 kthread_stop(dev->thread); 183 kthread_stop(dev->thread);
184#endif
185err_out_rm_attr:
186 w1_destroy_master_attributes(dev);
142err_out_free_dev: 187err_out_free_dev:
143 w1_free_dev(dev); 188 w1_free_dev(dev);
144 189
@@ -148,10 +193,21 @@ err_out_free_dev:
148void __w1_remove_master_device(struct w1_master *dev) 193void __w1_remove_master_device(struct w1_master *dev)
149{ 194{
150 struct w1_netlink_msg msg; 195 struct w1_netlink_msg msg;
196 struct w1_slave *sl, *sln;
151 197
152 set_bit(W1_MASTER_NEED_EXIT, &dev->flags);
153 kthread_stop(dev->thread); 198 kthread_stop(dev->thread);
154 199
200 mutex_lock(&w1_mlock);
201 list_del(&dev->w1_master_entry);
202 mutex_unlock(&w1_mlock);
203
204 mutex_lock(&dev->mutex);
205 list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry)
206 w1_slave_detach(sl);
207 w1_destroy_master_attributes(dev);
208 mutex_unlock(&dev->mutex);
209 atomic_dec(&dev->refcnt);
210
155 while (atomic_read(&dev->refcnt)) { 211 while (atomic_read(&dev->refcnt)) {
156 dev_info(&dev->dev, "Waiting for %s to become free: refcnt=%d.\n", 212 dev_info(&dev->dev, "Waiting for %s to become free: refcnt=%d.\n",
157 dev->name, atomic_read(&dev->refcnt)); 213 dev->name, atomic_read(&dev->refcnt));
diff --git a/drivers/w1/w1_io.c b/drivers/w1/w1_io.c
index 30b6fbf83bd4..f4f82f1f486e 100644
--- a/drivers/w1/w1_io.c
+++ b/drivers/w1/w1_io.c
@@ -93,6 +93,40 @@ static void w1_write_bit(struct w1_master *dev, int bit)
93} 93}
94 94
95/** 95/**
96 * Pre-write operation, currently only supporting strong pullups.
97 * Program the hardware for a strong pullup, if one has been requested and
98 * the hardware supports it.
99 *
100 * @param dev the master device
101 */
102static void w1_pre_write(struct w1_master *dev)
103{
104 if (dev->pullup_duration &&
105 dev->enable_pullup && dev->bus_master->set_pullup) {
106 dev->bus_master->set_pullup(dev->bus_master->data,
107 dev->pullup_duration);
108 }
109}
110
111/**
112 * Post-write operation, currently only supporting strong pullups.
113 * If a strong pullup was requested, clear it if the hardware supports
114 * them, or execute the delay otherwise, in either case clear the request.
115 *
116 * @param dev the master device
117 */
118static void w1_post_write(struct w1_master *dev)
119{
120 if (dev->pullup_duration) {
121 if (dev->enable_pullup && dev->bus_master->set_pullup)
122 dev->bus_master->set_pullup(dev->bus_master->data, 0);
123 else
124 msleep(dev->pullup_duration);
125 dev->pullup_duration = 0;
126 }
127}
128
129/**
96 * Writes 8 bits. 130 * Writes 8 bits.
97 * 131 *
98 * @param dev the master device 132 * @param dev the master device
@@ -102,11 +136,17 @@ void w1_write_8(struct w1_master *dev, u8 byte)
102{ 136{
103 int i; 137 int i;
104 138
105 if (dev->bus_master->write_byte) 139 if (dev->bus_master->write_byte) {
140 w1_pre_write(dev);
106 dev->bus_master->write_byte(dev->bus_master->data, byte); 141 dev->bus_master->write_byte(dev->bus_master->data, byte);
142 }
107 else 143 else
108 for (i = 0; i < 8; ++i) 144 for (i = 0; i < 8; ++i) {
145 if (i == 7)
146 w1_pre_write(dev);
109 w1_touch_bit(dev, (byte >> i) & 0x1); 147 w1_touch_bit(dev, (byte >> i) & 0x1);
148 }
149 w1_post_write(dev);
110} 150}
111EXPORT_SYMBOL_GPL(w1_write_8); 151EXPORT_SYMBOL_GPL(w1_write_8);
112 152
@@ -203,11 +243,14 @@ void w1_write_block(struct w1_master *dev, const u8 *buf, int len)
203{ 243{
204 int i; 244 int i;
205 245
206 if (dev->bus_master->write_block) 246 if (dev->bus_master->write_block) {
247 w1_pre_write(dev);
207 dev->bus_master->write_block(dev->bus_master->data, buf, len); 248 dev->bus_master->write_block(dev->bus_master->data, buf, len);
249 }
208 else 250 else
209 for (i = 0; i < len; ++i) 251 for (i = 0; i < len; ++i)
210 w1_write_8(dev, buf[i]); 252 w1_write_8(dev, buf[i]); /* calls w1_pre_write */
253 w1_post_write(dev);
211} 254}
212EXPORT_SYMBOL_GPL(w1_write_block); 255EXPORT_SYMBOL_GPL(w1_write_block);
213 256
@@ -250,12 +293,24 @@ int w1_reset_bus(struct w1_master *dev)
250 result = dev->bus_master->reset_bus(dev->bus_master->data) & 0x1; 293 result = dev->bus_master->reset_bus(dev->bus_master->data) & 0x1;
251 else { 294 else {
252 dev->bus_master->write_bit(dev->bus_master->data, 0); 295 dev->bus_master->write_bit(dev->bus_master->data, 0);
296 /* minimum 480, max ? us
297 * be nice and sleep, except 18b20 spec lists 960us maximum,
298 * so until we can sleep with microsecond accuracy, spin.
299 * Feel free to come up with some other way to give up the
300 * cpu for such a short amount of time AND get it back in
301 * the maximum amount of time.
302 */
253 w1_delay(480); 303 w1_delay(480);
254 dev->bus_master->write_bit(dev->bus_master->data, 1); 304 dev->bus_master->write_bit(dev->bus_master->data, 1);
255 w1_delay(70); 305 w1_delay(70);
256 306
257 result = dev->bus_master->read_bit(dev->bus_master->data) & 0x1; 307 result = dev->bus_master->read_bit(dev->bus_master->data) & 0x1;
258 w1_delay(410); 308 /* minmum 70 (above) + 410 = 480 us
309 * There aren't any timing requirements between a reset and
310 * the following transactions. Sleeping is safe here.
311 */
312 /* w1_delay(410); min required time */
313 msleep(1);
259 } 314 }
260 315
261 return result; 316 return result;
@@ -277,7 +332,8 @@ void w1_search_devices(struct w1_master *dev, u8 search_type, w1_slave_found_cal
277{ 332{
278 dev->attempts++; 333 dev->attempts++;
279 if (dev->bus_master->search) 334 if (dev->bus_master->search)
280 dev->bus_master->search(dev->bus_master->data, search_type, cb); 335 dev->bus_master->search(dev->bus_master->data, dev,
336 search_type, cb);
281 else 337 else
282 w1_search(dev, search_type, cb); 338 w1_search(dev, search_type, cb);
283} 339}
@@ -305,3 +361,20 @@ int w1_reset_select_slave(struct w1_slave *sl)
305 return 0; 361 return 0;
306} 362}
307EXPORT_SYMBOL_GPL(w1_reset_select_slave); 363EXPORT_SYMBOL_GPL(w1_reset_select_slave);
364
365/**
366 * Put out a strong pull-up of the specified duration after the next write
367 * operation. Not all hardware supports strong pullups. Hardware that
368 * doesn't support strong pullups will sleep for the given time after the
369 * write operation without a strong pullup. This is a one shot request for
370 * the next write, specifying zero will clear a previous request.
371 * The w1 master lock must be held.
372 *
373 * @param delay time in milliseconds
374 * @return 0=success, anything else=error
375 */
376void w1_next_pullup(struct w1_master *dev, int delay)
377{
378 dev->pullup_duration = delay;
379}
380EXPORT_SYMBOL_GPL(w1_next_pullup);