Linux/m68k driver for MNT ZZ9000
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

217 lines
6.5 KiB

  1. /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
  2. #include <linux/console.h>
  3. #include <linux/module.h>
  4. #include <linux/zorro.h>
  5. #include <asm/amigahw.h>
  6. #include "zz9000.h"
  7. static struct zz9000_platform_data *zz9000_data = NULL;
  8. struct zz9000_platform_data *get_zz9000_data(void)
  9. {
  10. return zz9000_data;
  11. }
  12. EXPORT_SYMBOL_GPL(get_zz9000_data);
  13. static ssize_t zz9000_show(struct kobject *kobj, struct kobj_attribute *attr,
  14. char *buf)
  15. {
  16. int pos = 0;
  17. uint16_t temp;
  18. pos += sprintf(buf + pos, "MNT ZZ9000 Zorro %s found at 0x%08x\n",
  19. is_zorro3(zz9000_data->zdev) ? "III" : "II", zz9000_data->zdev->resource.start);
  20. pos += sprintf(buf + pos, " driver version: %s\n", ZZ9000_VERSION);
  21. pos += sprintf(buf + pos, " HW version: %d\n", zz_readw(MNTZZ_HW_VERSION));
  22. pos += sprintf(buf + pos, " FW version: %d.%d\n", zz_readw(MNTZZ_FW_VERSION) >> 8,
  23. zz_readw(MNTZZ_FW_VERSION) & 0xff);
  24. temp = zz_readw(MNTZZ_TEMPERATURE);
  25. pos += sprintf(buf + pos, " Temperature: %d.%02d°C\n", temp / 10, temp % 10);
  26. temp = zz_readw(MNTZZ_VOLTAGE_AUX);
  27. pos += sprintf(buf + pos, " Voltage Vaux: %d.%02dV\n", temp / 100, temp % 100);
  28. temp = zz_readw(MNTZZ_VOLTAGE_INT);
  29. pos += sprintf(buf + pos, " Voltage Vint: %d.%02dV\n", temp / 100, temp % 100);
  30. printk(KERN_INFO "Bytes read: %d\n", pos);
  31. }
  32. static ssize_t zz9000_store(struct kobject *kobj, struct kobj_attribute *attr,
  33. const char *buf, size_t count)
  34. {
  35. // Nothing to do here.
  36. return count;
  37. }
  38. static struct kobj_attribute zz9000_info_attribute =
  39. __ATTR(info, 0664, zz9000_show, zz9000_store);
  40. static void zz9000_remove(struct zorro_dev *zdev)
  41. {
  42. struct zz9000_platform_data *zz9000_data = zorro_get_drvdata(zdev);
  43. uint32_t board = zdev->resource.start;
  44. if (zz9000_data->sysfs_root)
  45. root_device_unregister(zz9000_data->sysfs_root);
  46. if (zz9000_data->registers)
  47. iounmap(zz9000_data->registers);
  48. if (zz9000_data->eth_rx_mem)
  49. iounmap(zz9000_data->eth_rx_mem);
  50. if (zz9000_data->eth_tx_mem)
  51. iounmap(zz9000_data->eth_tx_mem);
  52. if (zz9000_data->usb_mem)
  53. iounmap(zz9000_data->usb_mem);
  54. if (zz9000_data->fb_mem)
  55. iounmap(zz9000_data->fb_mem);
  56. if (zz9000_data->res[0])
  57. release_mem_region(board + MNTZZ_REG_BASE, MNTZZ_REG_SIZE);
  58. if (zz9000_data->res[1])
  59. release_mem_region(board + MNTZZ_RX_BASE, MNTZZ_RX_SIZE);
  60. if (zz9000_data->res[2])
  61. release_mem_region(board + MNTZZ_TX_BASE, MNTZZ_TX_SIZE);
  62. if (zz9000_data->res[3])
  63. release_mem_region(board + MNTZZ_USB_BASE, MNTZZ_USB_SIZE);
  64. if (zz9000_data->res[4])
  65. release_mem_region(board + MNTZZ_FB_BASE, zz9000_data->fb_size);
  66. }
  67. static int zz9000_probe(struct zorro_dev *zdev,
  68. const struct zorro_device_id *ent)
  69. {
  70. int ret = 0;
  71. uint16_t temp;
  72. uint32_t board = zdev->resource.start;
  73. printk(KERN_INFO "MNT ZZ9000 driver v%s\n", ZZ9000_VERSION);
  74. zz9000_data =
  75. devm_kzalloc(&zdev->dev, sizeof(*zz9000_data), GFP_KERNEL);
  76. if (!zz9000_data) {
  77. ret = -ENOMEM;
  78. goto out;
  79. }
  80. zorro_set_drvdata(zdev, zz9000_data);
  81. /* How much memory is visible? */
  82. zz9000_data->fb_size = is_zorro3(zdev) ? MNTZZ_FB_SIZE_ZIII : MNTZZ_FB_SIZE_ZII;
  83. zz9000_data->res[0] = request_mem_region(board + MNTZZ_REG_BASE, MNTZZ_REG_SIZE, "ZZ9000 Registers");
  84. if (!zz9000_data->res[0]) {
  85. dev_err(&zdev->dev, "Could not reserve register region.\n");
  86. ret = -ENXIO;
  87. goto cleanup;
  88. }
  89. zz9000_data->res[1] = request_mem_region(board + MNTZZ_RX_BASE, MNTZZ_RX_SIZE, "ZZ9000 Network RX");
  90. if (!zz9000_data->res[1]) {
  91. dev_err(&zdev->dev, "Could not reserve network RX region.\n");
  92. ret = -ENXIO;
  93. goto cleanup;
  94. }
  95. zz9000_data->res[2] = request_mem_region(board + MNTZZ_TX_BASE, MNTZZ_TX_SIZE, "ZZ9000 Network TX");
  96. if (!zz9000_data->res[2]) {
  97. dev_err(&zdev->dev, "Could not reserve network TX region.\n");
  98. ret = -ENXIO;
  99. goto cleanup;
  100. }
  101. zz9000_data->res[3] = request_mem_region(board + MNTZZ_USB_BASE, MNTZZ_USB_SIZE, "ZZ9000 USB");
  102. if (!zz9000_data->res[3]) {
  103. dev_err(&zdev->dev, "Could not reserve USB buffer region.\n");
  104. ret = -ENXIO;
  105. goto cleanup;
  106. }
  107. zz9000_data->res[4] = request_mem_region(board + MNTZZ_FB_BASE, zz9000_data->fb_size, "ZZ9000 Framebuffer");
  108. if (!zz9000_data->res[4]) {
  109. dev_err(&zdev->dev, "Could not reserve framebuffer region.\n");
  110. ret = -ENXIO;
  111. goto cleanup;
  112. }
  113. zz9000_data->registers = z_ioremap(board + MNTZZ_REG_BASE, MNTZZ_REG_SIZE);
  114. zz9000_data->eth_rx_mem = z_ioremap(board + MNTZZ_RX_BASE, MNTZZ_RX_SIZE);
  115. zz9000_data->eth_tx_mem = z_ioremap(board + MNTZZ_TX_BASE, MNTZZ_TX_SIZE);
  116. zz9000_data->usb_mem = z_ioremap(board + MNTZZ_USB_BASE, MNTZZ_USB_SIZE);
  117. /* access the videomem with writethrough cache */
  118. zz9000_data->fb_mem = ioremap_wt(board + MNTZZ_FB_BASE, zz9000_data->fb_size);
  119. zz9000_data->zdev = zdev;
  120. if (!zz9000_data->registers || !zz9000_data->eth_rx_mem ||
  121. !zz9000_data->eth_tx_mem || !zz9000_data->usb_mem ||
  122. !zz9000_data->fb_mem) {
  123. dev_err(&zdev->dev, "Could not ioremap device memory.\n");
  124. ret = -ENXIO;
  125. goto cleanup;
  126. }
  127. printk(KERN_INFO "MNT ZZ9000 Zorro %s found at 0x%08x\n",
  128. is_zorro3(zdev) ? "III" : "II", board);
  129. printk(KERN_INFO " HW version %d\n", zz_readw(MNTZZ_HW_VERSION));
  130. printk(KERN_INFO " FW version %d.%d\n", zz_readw(MNTZZ_FW_VERSION) >> 8,
  131. zz_readw(MNTZZ_FW_VERSION) & 0xff);
  132. temp = zz_readw(MNTZZ_TEMPERATURE);
  133. printk(KERN_INFO " Temperature %d.%02d degree C\n", temp / 10, temp % 10);
  134. temp = zz_readw(MNTZZ_VOLTAGE_AUX);
  135. printk(KERN_INFO " Voltage Vaux %d.%02dV\n", temp / 100, temp % 100);
  136. temp = zz_readw(MNTZZ_VOLTAGE_INT);
  137. printk(KERN_INFO " Voltage Vint %d.%02dV\n", temp / 100, temp % 100);
  138. zz9000_data->sysfs_root = root_device_register("zz9000");
  139. if(!zz9000_data->sysfs_root) {
  140. ret = -ENOMEM;
  141. goto cleanup;
  142. }
  143. ret = sysfs_create_file(&zz9000_data->sysfs_root->kobj,
  144. &zz9000_info_attribute.attr);
  145. if (ret) {
  146. pr_debug("Failed to create /sys/devices/zz9000/info\n");
  147. }
  148. if (!ret)
  149. return 0;
  150. cleanup:
  151. zz9000_remove(zdev);
  152. out:
  153. return ret;
  154. }
  155. static const struct zorro_device_id zz9000_zorro_tbl[] = {
  156. {ZORRO_PROD_MNT_ZZ9000_ZII},
  157. {ZORRO_PROD_MNT_ZZ9000_ZIII},
  158. {0}
  159. };
  160. MODULE_DEVICE_TABLE(zorro, zz9000_zorro_tbl);
  161. static struct zorro_driver zz9000_driver = {
  162. .name = "zz9000",
  163. .id_table = zz9000_zorro_tbl,
  164. .probe = zz9000_probe,
  165. .remove = zz9000_remove,
  166. };
  167. static int __init zz9000_init(void)
  168. {
  169. return zorro_register_driver(&zz9000_driver);
  170. }
  171. module_init(zz9000_init);
  172. static void __exit zz9000_exit(void)
  173. {
  174. zorro_unregister_driver(&zz9000_driver);
  175. }
  176. module_exit(zz9000_exit);
  177. MODULE_DESCRIPTION("MNT ZZ9000 core driver");
  178. MODULE_AUTHOR("Stefan Reinauer <stefan.reinauer@coreboot.org>");
  179. MODULE_LICENSE("GPL");