sh_pfc.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  1. /*
  2. * Pinmuxed GPIO support for SuperH.
  3. * Copy from linux kernel driver/sh/pfc.c
  4. *
  5. * Copyright (C) 2008 Magnus Damm
  6. *
  7. * This file is subject to the terms and conditions of the GNU General Public
  8. * License. See the file "COPYING" in the main directory of this archive
  9. * for more details.
  10. */
  11. #include <common.h>
  12. #include <asm/bitops.h>
  13. #include <asm/io.h>
  14. #include <sh_pfc.h>
  15. static struct pinmux_info *gpioc;
  16. #define pfc_phys_to_virt(p, a) ((void *)a)
  17. static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r)
  18. {
  19. if (enum_id < r->begin)
  20. return 0;
  21. if (enum_id > r->end)
  22. return 0;
  23. return 1;
  24. }
  25. static unsigned long gpio_read_raw_reg(void *mapped_reg,
  26. unsigned long reg_width)
  27. {
  28. switch (reg_width) {
  29. case 8:
  30. return readb(mapped_reg);
  31. case 16:
  32. return readw(mapped_reg);
  33. case 32:
  34. return readl(mapped_reg);
  35. }
  36. BUG();
  37. return 0;
  38. }
  39. static void gpio_write_raw_reg(void *mapped_reg,
  40. unsigned long reg_width,
  41. unsigned long data)
  42. {
  43. switch (reg_width) {
  44. case 8:
  45. writeb(data, mapped_reg);
  46. return;
  47. case 16:
  48. writew(data, mapped_reg);
  49. return;
  50. case 32:
  51. writel(data, mapped_reg);
  52. return;
  53. }
  54. BUG();
  55. }
  56. static int gpio_read_bit(struct pinmux_data_reg *dr,
  57. unsigned long in_pos)
  58. {
  59. unsigned long pos;
  60. pos = dr->reg_width - (in_pos + 1);
  61. debug("read_bit: addr = %lx, pos = %ld, "
  62. "r_width = %ld\n", dr->reg, pos, dr->reg_width);
  63. return (gpio_read_raw_reg(dr->mapped_reg, dr->reg_width) >> pos) & 1;
  64. }
  65. static void gpio_write_bit(struct pinmux_data_reg *dr,
  66. unsigned long in_pos, unsigned long value)
  67. {
  68. unsigned long pos;
  69. pos = dr->reg_width - (in_pos + 1);
  70. debug("write_bit addr = %lx, value = %d, pos = %ld, "
  71. "r_width = %ld\n",
  72. dr->reg, !!value, pos, dr->reg_width);
  73. if (value)
  74. __set_bit(pos, &dr->reg_shadow);
  75. else
  76. __clear_bit(pos, &dr->reg_shadow);
  77. gpio_write_raw_reg(dr->mapped_reg, dr->reg_width, dr->reg_shadow);
  78. }
  79. static void config_reg_helper(struct pinmux_info *gpioc,
  80. struct pinmux_cfg_reg *crp,
  81. unsigned long in_pos,
  82. #if 0
  83. void __iomem **mapped_regp,
  84. #else
  85. void **mapped_regp,
  86. #endif
  87. unsigned long *maskp,
  88. unsigned long *posp)
  89. {
  90. int k;
  91. *mapped_regp = pfc_phys_to_virt(gpioc, crp->reg);
  92. if (crp->field_width) {
  93. *maskp = (1 << crp->field_width) - 1;
  94. *posp = crp->reg_width - ((in_pos + 1) * crp->field_width);
  95. } else {
  96. *maskp = (1 << crp->var_field_width[in_pos]) - 1;
  97. *posp = crp->reg_width;
  98. for (k = 0; k <= in_pos; k++)
  99. *posp -= crp->var_field_width[k];
  100. }
  101. }
  102. static int read_config_reg(struct pinmux_info *gpioc,
  103. struct pinmux_cfg_reg *crp,
  104. unsigned long field)
  105. {
  106. void *mapped_reg;
  107. unsigned long mask, pos;
  108. config_reg_helper(gpioc, crp, field, &mapped_reg, &mask, &pos);
  109. debug("read_reg: addr = %lx, field = %ld, "
  110. "r_width = %ld, f_width = %ld\n",
  111. crp->reg, field, crp->reg_width, crp->field_width);
  112. return (gpio_read_raw_reg(mapped_reg, crp->reg_width) >> pos) & mask;
  113. }
  114. static void write_config_reg(struct pinmux_info *gpioc,
  115. struct pinmux_cfg_reg *crp,
  116. unsigned long field, unsigned long value)
  117. {
  118. void *mapped_reg;
  119. unsigned long mask, pos, data;
  120. config_reg_helper(gpioc, crp, field, &mapped_reg, &mask, &pos);
  121. debug("write_reg addr = %lx, value = %ld, field = %ld, "
  122. "r_width = %ld, f_width = %ld\n",
  123. crp->reg, value, field, crp->reg_width, crp->field_width);
  124. mask = ~(mask << pos);
  125. value = value << pos;
  126. data = gpio_read_raw_reg(mapped_reg, crp->reg_width);
  127. data &= mask;
  128. data |= value;
  129. if (gpioc->unlock_reg)
  130. gpio_write_raw_reg(pfc_phys_to_virt(gpioc, gpioc->unlock_reg),
  131. 32, ~data);
  132. gpio_write_raw_reg(mapped_reg, crp->reg_width, data);
  133. }
  134. static int setup_data_reg(struct pinmux_info *gpioc, unsigned gpio)
  135. {
  136. struct pinmux_gpio *gpiop = &gpioc->gpios[gpio];
  137. struct pinmux_data_reg *data_reg;
  138. int k, n;
  139. if (!enum_in_range(gpiop->enum_id, &gpioc->data))
  140. return -1;
  141. k = 0;
  142. while (1) {
  143. data_reg = gpioc->data_regs + k;
  144. if (!data_reg->reg_width)
  145. break;
  146. data_reg->mapped_reg = pfc_phys_to_virt(gpioc, data_reg->reg);
  147. for (n = 0; n < data_reg->reg_width; n++) {
  148. if (data_reg->enum_ids[n] == gpiop->enum_id) {
  149. gpiop->flags &= ~PINMUX_FLAG_DREG;
  150. gpiop->flags |= (k << PINMUX_FLAG_DREG_SHIFT);
  151. gpiop->flags &= ~PINMUX_FLAG_DBIT;
  152. gpiop->flags |= (n << PINMUX_FLAG_DBIT_SHIFT);
  153. return 0;
  154. }
  155. }
  156. k++;
  157. }
  158. BUG();
  159. return -1;
  160. }
  161. static void setup_data_regs(struct pinmux_info *gpioc)
  162. {
  163. struct pinmux_data_reg *drp;
  164. int k;
  165. for (k = gpioc->first_gpio; k <= gpioc->last_gpio; k++)
  166. setup_data_reg(gpioc, k);
  167. k = 0;
  168. while (1) {
  169. drp = gpioc->data_regs + k;
  170. if (!drp->reg_width)
  171. break;
  172. drp->reg_shadow = gpio_read_raw_reg(drp->mapped_reg,
  173. drp->reg_width);
  174. k++;
  175. }
  176. }
  177. static int get_data_reg(struct pinmux_info *gpioc, unsigned gpio,
  178. struct pinmux_data_reg **drp, int *bitp)
  179. {
  180. struct pinmux_gpio *gpiop = &gpioc->gpios[gpio];
  181. int k, n;
  182. if (!enum_in_range(gpiop->enum_id, &gpioc->data))
  183. return -1;
  184. k = (gpiop->flags & PINMUX_FLAG_DREG) >> PINMUX_FLAG_DREG_SHIFT;
  185. n = (gpiop->flags & PINMUX_FLAG_DBIT) >> PINMUX_FLAG_DBIT_SHIFT;
  186. *drp = gpioc->data_regs + k;
  187. *bitp = n;
  188. return 0;
  189. }
  190. static int get_config_reg(struct pinmux_info *gpioc, pinmux_enum_t enum_id,
  191. struct pinmux_cfg_reg **crp,
  192. int *fieldp, int *valuep,
  193. unsigned long **cntp)
  194. {
  195. struct pinmux_cfg_reg *config_reg;
  196. unsigned long r_width, f_width, curr_width, ncomb;
  197. int k, m, n, pos, bit_pos;
  198. k = 0;
  199. while (1) {
  200. config_reg = gpioc->cfg_regs + k;
  201. r_width = config_reg->reg_width;
  202. f_width = config_reg->field_width;
  203. if (!r_width)
  204. break;
  205. pos = 0;
  206. m = 0;
  207. for (bit_pos = 0; bit_pos < r_width; bit_pos += curr_width) {
  208. if (f_width)
  209. curr_width = f_width;
  210. else
  211. curr_width = config_reg->var_field_width[m];
  212. ncomb = 1 << curr_width;
  213. for (n = 0; n < ncomb; n++) {
  214. if (config_reg->enum_ids[pos + n] == enum_id) {
  215. *crp = config_reg;
  216. *fieldp = m;
  217. *valuep = n;
  218. *cntp = &config_reg->cnt[m];
  219. return 0;
  220. }
  221. }
  222. pos += ncomb;
  223. m++;
  224. }
  225. k++;
  226. }
  227. return -1;
  228. }
  229. static int get_gpio_enum_id(struct pinmux_info *gpioc, unsigned gpio,
  230. int pos, pinmux_enum_t *enum_idp)
  231. {
  232. pinmux_enum_t enum_id = gpioc->gpios[gpio].enum_id;
  233. pinmux_enum_t *data = gpioc->gpio_data;
  234. int k;
  235. if (!enum_in_range(enum_id, &gpioc->data)) {
  236. if (!enum_in_range(enum_id, &gpioc->mark)) {
  237. debug("non data/mark enum_id for gpio %d\n", gpio);
  238. return -1;
  239. }
  240. }
  241. if (pos) {
  242. *enum_idp = data[pos + 1];
  243. return pos + 1;
  244. }
  245. for (k = 0; k < gpioc->gpio_data_size; k++) {
  246. if (data[k] == enum_id) {
  247. *enum_idp = data[k + 1];
  248. return k + 1;
  249. }
  250. }
  251. debug("cannot locate data/mark enum_id for gpio %d\n", gpio);
  252. return -1;
  253. }
  254. enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE };
  255. static int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio,
  256. int pinmux_type, int cfg_mode)
  257. {
  258. struct pinmux_cfg_reg *cr = NULL;
  259. pinmux_enum_t enum_id;
  260. struct pinmux_range *range;
  261. int in_range, pos, field, value;
  262. unsigned long *cntp;
  263. switch (pinmux_type) {
  264. case PINMUX_TYPE_FUNCTION:
  265. range = NULL;
  266. break;
  267. case PINMUX_TYPE_OUTPUT:
  268. range = &gpioc->output;
  269. break;
  270. case PINMUX_TYPE_INPUT:
  271. range = &gpioc->input;
  272. break;
  273. case PINMUX_TYPE_INPUT_PULLUP:
  274. range = &gpioc->input_pu;
  275. break;
  276. case PINMUX_TYPE_INPUT_PULLDOWN:
  277. range = &gpioc->input_pd;
  278. break;
  279. default:
  280. goto out_err;
  281. }
  282. pos = 0;
  283. enum_id = 0;
  284. field = 0;
  285. value = 0;
  286. while (1) {
  287. pos = get_gpio_enum_id(gpioc, gpio, pos, &enum_id);
  288. if (pos <= 0)
  289. goto out_err;
  290. if (!enum_id)
  291. break;
  292. /* first check if this is a function enum */
  293. in_range = enum_in_range(enum_id, &gpioc->function);
  294. if (!in_range) {
  295. /* not a function enum */
  296. if (range) {
  297. /*
  298. * other range exists, so this pin is
  299. * a regular GPIO pin that now is being
  300. * bound to a specific direction.
  301. *
  302. * for this case we only allow function enums
  303. * and the enums that match the other range.
  304. */
  305. in_range = enum_in_range(enum_id, range);
  306. /*
  307. * special case pass through for fixed
  308. * input-only or output-only pins without
  309. * function enum register association.
  310. */
  311. if (in_range && enum_id == range->force)
  312. continue;
  313. } else {
  314. /*
  315. * no other range exists, so this pin
  316. * must then be of the function type.
  317. *
  318. * allow function type pins to select
  319. * any combination of function/in/out
  320. * in their MARK lists.
  321. */
  322. in_range = 1;
  323. }
  324. }
  325. if (!in_range)
  326. continue;
  327. if (get_config_reg(gpioc, enum_id, &cr,
  328. &field, &value, &cntp) != 0)
  329. goto out_err;
  330. switch (cfg_mode) {
  331. case GPIO_CFG_DRYRUN:
  332. if (!*cntp ||
  333. (read_config_reg(gpioc, cr, field) != value))
  334. continue;
  335. break;
  336. case GPIO_CFG_REQ:
  337. write_config_reg(gpioc, cr, field, value);
  338. *cntp = *cntp + 1;
  339. break;
  340. case GPIO_CFG_FREE:
  341. *cntp = *cntp - 1;
  342. break;
  343. }
  344. }
  345. return 0;
  346. out_err:
  347. return -1;
  348. }
  349. #if 0
  350. static DEFINE_SPINLOCK(gpio_lock);
  351. static struct pinmux_info *chip_to_pinmux(struct gpio_chip *chip)
  352. {
  353. return container_of(chip, struct pinmux_info, chip);
  354. }
  355. #endif
  356. static int sh_gpio_request(unsigned offset)
  357. {
  358. struct pinmux_data_reg *dummy;
  359. int i, ret, pinmux_type;
  360. ret = -1;
  361. if (!gpioc)
  362. goto err_out;
  363. if ((gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE) != PINMUX_TYPE_NONE)
  364. goto err_out;
  365. /* setup pin function here if no data is associated with pin */
  366. if (get_data_reg(gpioc, offset, &dummy, &i) != 0)
  367. pinmux_type = PINMUX_TYPE_FUNCTION;
  368. else
  369. pinmux_type = PINMUX_TYPE_GPIO;
  370. if (pinmux_type == PINMUX_TYPE_FUNCTION) {
  371. if (pinmux_config_gpio(gpioc, offset,
  372. pinmux_type,
  373. GPIO_CFG_DRYRUN) != 0)
  374. goto err_out;
  375. if (pinmux_config_gpio(gpioc, offset,
  376. pinmux_type,
  377. GPIO_CFG_REQ) != 0)
  378. BUG();
  379. }
  380. gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE;
  381. gpioc->gpios[offset].flags |= pinmux_type;
  382. ret = 0;
  383. err_out:
  384. return ret;
  385. }
  386. static void sh_gpio_free(unsigned offset)
  387. {
  388. int pinmux_type;
  389. if (!gpioc)
  390. return;
  391. pinmux_type = gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE;
  392. pinmux_config_gpio(gpioc, offset, pinmux_type, GPIO_CFG_FREE);
  393. gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE;
  394. gpioc->gpios[offset].flags |= PINMUX_TYPE_NONE;
  395. }
  396. static int pinmux_direction(struct pinmux_info *gpioc,
  397. unsigned gpio, int new_pinmux_type)
  398. {
  399. int pinmux_type;
  400. int ret = -1;
  401. if (!gpioc)
  402. goto err_out;
  403. pinmux_type = gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE;
  404. switch (pinmux_type) {
  405. case PINMUX_TYPE_GPIO:
  406. break;
  407. case PINMUX_TYPE_OUTPUT:
  408. case PINMUX_TYPE_INPUT:
  409. case PINMUX_TYPE_INPUT_PULLUP:
  410. case PINMUX_TYPE_INPUT_PULLDOWN:
  411. pinmux_config_gpio(gpioc, gpio, pinmux_type, GPIO_CFG_FREE);
  412. break;
  413. default:
  414. goto err_out;
  415. }
  416. if (pinmux_config_gpio(gpioc, gpio,
  417. new_pinmux_type,
  418. GPIO_CFG_DRYRUN) != 0)
  419. goto err_out;
  420. if (pinmux_config_gpio(gpioc, gpio,
  421. new_pinmux_type,
  422. GPIO_CFG_REQ) != 0)
  423. BUG();
  424. gpioc->gpios[gpio].flags &= ~PINMUX_FLAG_TYPE;
  425. gpioc->gpios[gpio].flags |= new_pinmux_type;
  426. ret = 0;
  427. err_out:
  428. return ret;
  429. }
  430. static int sh_gpio_direction_input(unsigned offset)
  431. {
  432. return pinmux_direction(gpioc, offset, PINMUX_TYPE_INPUT);
  433. }
  434. static void sh_gpio_set_value(struct pinmux_info *gpioc,
  435. unsigned gpio, int value)
  436. {
  437. struct pinmux_data_reg *dr = NULL;
  438. int bit = 0;
  439. if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0)
  440. BUG();
  441. else
  442. gpio_write_bit(dr, bit, value);
  443. }
  444. static int sh_gpio_direction_output(unsigned offset, int value)
  445. {
  446. sh_gpio_set_value(gpioc, offset, value);
  447. return pinmux_direction(gpioc, offset, PINMUX_TYPE_OUTPUT);
  448. }
  449. static int sh_gpio_get_value(struct pinmux_info *gpioc, unsigned gpio)
  450. {
  451. struct pinmux_data_reg *dr = NULL;
  452. int bit = 0;
  453. if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0)
  454. return -1;
  455. return gpio_read_bit(dr, bit);
  456. }
  457. static int sh_gpio_get(unsigned offset)
  458. {
  459. return sh_gpio_get_value(gpioc, offset);
  460. }
  461. static void sh_gpio_set(unsigned offset, int value)
  462. {
  463. sh_gpio_set_value(gpioc, offset, value);
  464. }
  465. int register_pinmux(struct pinmux_info *pip)
  466. {
  467. if (pip != NULL) {
  468. gpioc = pip;
  469. debug("%s deregistering\n", pip->name);
  470. setup_data_regs(gpioc);
  471. }
  472. return 0;
  473. }
  474. int unregister_pinmux(struct pinmux_info *pip)
  475. {
  476. debug("%s deregistering\n", pip->name);
  477. if (gpioc != pip)
  478. return -1;
  479. gpioc = NULL;
  480. return 0;
  481. }
  482. int gpio_request(unsigned gpio, const char *label)
  483. {
  484. sh_gpio_request(gpio);
  485. return 0;
  486. }
  487. int gpio_free(unsigned gpio)
  488. {
  489. sh_gpio_free(gpio);
  490. return 0;
  491. }
  492. int gpio_direction_input(unsigned gpio)
  493. {
  494. return sh_gpio_direction_input(gpio);
  495. }
  496. int gpio_direction_output(unsigned gpio, int value)
  497. {
  498. return sh_gpio_direction_output(gpio, value);
  499. }
  500. void gpio_set_value(unsigned gpio, int value)
  501. {
  502. sh_gpio_set(gpio, value);
  503. }
  504. int gpio_get_value(unsigned gpio)
  505. {
  506. return sh_gpio_get(gpio);
  507. }