nintendo-otp.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Nintendo Wii and Wii U OTP driver
  4. *
  5. * This is a driver exposing the OTP of a Nintendo Wii or Wii U console.
  6. *
  7. * This memory contains common and per-console keys, signatures and
  8. * related data required to access peripherals.
  9. *
  10. * Based on reversed documentation from https://wiiubrew.org/wiki/Hardware/OTP
  11. *
  12. * Copyright (C) 2021 Emmanuel Gil Peyrot <[email protected]>
  13. */
  14. #include <linux/device.h>
  15. #include <linux/io.h>
  16. #include <linux/module.h>
  17. #include <linux/mod_devicetable.h>
  18. #include <linux/nvmem-provider.h>
  19. #include <linux/of_device.h>
  20. #include <linux/platform_device.h>
  21. #define HW_OTPCMD 0
  22. #define HW_OTPDATA 4
  23. #define OTP_READ 0x80000000
  24. #define BANK_SIZE 128
  25. #define WORD_SIZE 4
  26. struct nintendo_otp_priv {
  27. void __iomem *regs;
  28. };
  29. struct nintendo_otp_devtype_data {
  30. const char *name;
  31. unsigned int num_banks;
  32. };
  33. static const struct nintendo_otp_devtype_data hollywood_otp_data = {
  34. .name = "wii-otp",
  35. .num_banks = 1,
  36. };
  37. static const struct nintendo_otp_devtype_data latte_otp_data = {
  38. .name = "wiiu-otp",
  39. .num_banks = 8,
  40. };
  41. static int nintendo_otp_reg_read(void *context,
  42. unsigned int reg, void *_val, size_t bytes)
  43. {
  44. struct nintendo_otp_priv *priv = context;
  45. u32 *val = _val;
  46. int words = bytes / WORD_SIZE;
  47. u32 bank, addr;
  48. while (words--) {
  49. bank = (reg / BANK_SIZE) << 8;
  50. addr = (reg / WORD_SIZE) % (BANK_SIZE / WORD_SIZE);
  51. iowrite32be(OTP_READ | bank | addr, priv->regs + HW_OTPCMD);
  52. *val++ = ioread32be(priv->regs + HW_OTPDATA);
  53. reg += WORD_SIZE;
  54. }
  55. return 0;
  56. }
  57. static const struct of_device_id nintendo_otp_of_table[] = {
  58. { .compatible = "nintendo,hollywood-otp", .data = &hollywood_otp_data },
  59. { .compatible = "nintendo,latte-otp", .data = &latte_otp_data },
  60. {/* sentinel */},
  61. };
  62. MODULE_DEVICE_TABLE(of, nintendo_otp_of_table);
  63. static int nintendo_otp_probe(struct platform_device *pdev)
  64. {
  65. struct device *dev = &pdev->dev;
  66. const struct of_device_id *of_id =
  67. of_match_device(nintendo_otp_of_table, dev);
  68. struct resource *res;
  69. struct nvmem_device *nvmem;
  70. struct nintendo_otp_priv *priv;
  71. struct nvmem_config config = {
  72. .stride = WORD_SIZE,
  73. .word_size = WORD_SIZE,
  74. .reg_read = nintendo_otp_reg_read,
  75. .read_only = true,
  76. .root_only = true,
  77. };
  78. priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
  79. if (!priv)
  80. return -ENOMEM;
  81. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  82. priv->regs = devm_ioremap_resource(dev, res);
  83. if (IS_ERR(priv->regs))
  84. return PTR_ERR(priv->regs);
  85. if (of_id->data) {
  86. const struct nintendo_otp_devtype_data *data = of_id->data;
  87. config.name = data->name;
  88. config.size = data->num_banks * BANK_SIZE;
  89. }
  90. config.dev = dev;
  91. config.priv = priv;
  92. nvmem = devm_nvmem_register(dev, &config);
  93. return PTR_ERR_OR_ZERO(nvmem);
  94. }
  95. static struct platform_driver nintendo_otp_driver = {
  96. .probe = nintendo_otp_probe,
  97. .driver = {
  98. .name = "nintendo-otp",
  99. .of_match_table = nintendo_otp_of_table,
  100. },
  101. };
  102. module_platform_driver(nintendo_otp_driver);
  103. MODULE_AUTHOR("Emmanuel Gil Peyrot <[email protected]>");
  104. MODULE_DESCRIPTION("Nintendo Wii and Wii U OTP driver");
  105. MODULE_LICENSE("GPL v2");