nv17_gpio.c 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. /*
  2. * Copyright (C) 2009 Francisco Jerez.
  3. * All Rights Reserved.
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining
  6. * a copy of this software and associated documentation files (the
  7. * "Software"), to deal in the Software without restriction, including
  8. * without limitation the rights to use, copy, modify, merge, publish,
  9. * distribute, sublicense, and/or sell copies of the Software, and to
  10. * permit persons to whom the Software is furnished to do so, subject to
  11. * the following conditions:
  12. *
  13. * The above copyright notice and this permission notice (including the
  14. * next paragraph) shall be included in all copies or substantial
  15. * portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  18. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  20. * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
  21. * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  22. * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  23. * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  24. *
  25. */
  26. #include "drmP.h"
  27. #include "nouveau_drv.h"
  28. #include "nouveau_hw.h"
  29. static bool
  30. get_gpio_location(struct dcb_gpio_entry *ent, uint32_t *reg, uint32_t *shift,
  31. uint32_t *mask)
  32. {
  33. if (ent->line < 2) {
  34. *reg = NV_PCRTC_GPIO;
  35. *shift = ent->line * 16;
  36. *mask = 0x11;
  37. } else if (ent->line < 10) {
  38. *reg = NV_PCRTC_GPIO_EXT;
  39. *shift = (ent->line - 2) * 4;
  40. *mask = 0x3;
  41. } else if (ent->line < 14) {
  42. *reg = NV_PCRTC_850;
  43. *shift = (ent->line - 10) * 4;
  44. *mask = 0x3;
  45. } else {
  46. return false;
  47. }
  48. return true;
  49. }
  50. int
  51. nv17_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag)
  52. {
  53. struct dcb_gpio_entry *ent = nouveau_bios_gpio_entry(dev, tag);
  54. uint32_t reg, shift, mask, value;
  55. if (!ent)
  56. return -ENODEV;
  57. if (!get_gpio_location(ent, &reg, &shift, &mask))
  58. return -ENODEV;
  59. value = NVReadCRTC(dev, 0, reg) >> shift;
  60. return (ent->invert ? 1 : 0) ^ (value & 1);
  61. }
  62. int
  63. nv17_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state)
  64. {
  65. struct dcb_gpio_entry *ent = nouveau_bios_gpio_entry(dev, tag);
  66. uint32_t reg, shift, mask, value;
  67. if (!ent)
  68. return -ENODEV;
  69. if (!get_gpio_location(ent, &reg, &shift, &mask))
  70. return -ENODEV;
  71. value = ((ent->invert ? 1 : 0) ^ (state ? 1 : 0)) << shift;
  72. mask = ~(mask << shift);
  73. NVWriteCRTC(dev, 0, reg, value | (NVReadCRTC(dev, 0, reg) & mask));
  74. return 0;
  75. }