1f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto/* 2f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * Renesas USB driver 3f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * 4f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * Copyright (C) 2011 Renesas Solutions Corp. 5f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> 6f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * 7f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * This program is distributed in the hope that it will be useful, 8f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * but WITHOUT ANY WARRANTY; without even the implied warranty of 9f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * GNU General Public License for more details. 11f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * 12f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * You should have received a copy of the GNU General Public License 13f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * along with this program; if not, write to the Free Software 14f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 15f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * 16f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto */ 17f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto#include <linux/interrupt.h> 18f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 19f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto#include "./common.h" 20f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto#include "./mod.h" 21f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 22f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto#define usbhs_priv_to_modinfo(priv) (&priv->mod_info) 23b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto#define usbhs_mod_info_call(priv, func, param...) \ 24b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto({ \ 25b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto struct usbhs_mod_info *info; \ 26b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto info = usbhs_priv_to_modinfo(priv); \ 27b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto !info->func ? 0 : \ 28b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto info->func(param); \ 29b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto}) 30b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto 31b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto/* 32b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto * autonomy 33b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto * 34b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto * these functions are used if platform doesn't have external phy. 35b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto * -> there is no "notify_hotplug" callback from platform 36b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto * -> call "notify_hotplug" by itself 37b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto * -> use own interrupt to connect/disconnect 38b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto * -> it mean module clock is always ON 39b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto * ~~~~~~~~~~~~~~~~~~~~~~~~~ 40b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto */ 41b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimotostatic int usbhsm_autonomy_get_vbus(struct platform_device *pdev) 42b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto{ 43b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); 44b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto 45b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto return VBSTS & usbhs_read(priv, INTSTS0); 46b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto} 47b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto 48b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimotostatic int usbhsm_autonomy_irq_vbus(struct usbhs_priv *priv, 49b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto struct usbhs_irq_state *irq_state) 50b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto{ 51b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto struct platform_device *pdev = usbhs_priv_to_pdev(priv); 52b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto 53b4fcea2a71cafc59a749fa3ef88e51af8c2e3b37Kuninori Morimoto renesas_usbhs_call_notify_hotplug(pdev); 54b4fcea2a71cafc59a749fa3ef88e51af8c2e3b37Kuninori Morimoto 55b4fcea2a71cafc59a749fa3ef88e51af8c2e3b37Kuninori Morimoto return 0; 56b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto} 57b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto 58b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimotovoid usbhs_mod_autonomy_mode(struct usbhs_priv *priv) 59b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto{ 60b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto struct usbhs_mod_info *info = usbhs_priv_to_modinfo(priv); 61b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto 62b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto info->irq_vbus = usbhsm_autonomy_irq_vbus; 63482982062f1bc25ffb5383ab724d73d1a7af07cfKuninori Morimoto priv->pfunc.get_vbus = usbhsm_autonomy_get_vbus; 64b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto 65b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto usbhs_irq_callback_update(priv, NULL); 66b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto} 67f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 68f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto/* 69f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * host / gadget functions 70f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * 71f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * renesas_usbhs host/gadget can register itself by below functions. 72f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * these functions are called when probe 73f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * 74f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto */ 75f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimotovoid usbhs_mod_register(struct usbhs_priv *priv, struct usbhs_mod *mod, int id) 76f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto{ 77f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto struct usbhs_mod_info *info = usbhs_priv_to_modinfo(priv); 78f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 79f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto info->mod[id] = mod; 80f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto mod->priv = priv; 81f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto} 82f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 83f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimotostruct usbhs_mod *usbhs_mod_get(struct usbhs_priv *priv, int id) 84f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto{ 85f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto struct usbhs_mod_info *info = usbhs_priv_to_modinfo(priv); 86f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto struct usbhs_mod *ret = NULL; 87f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 88f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto switch (id) { 89f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto case USBHS_HOST: 90f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto case USBHS_GADGET: 91f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto ret = info->mod[id]; 92f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto break; 93f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto } 94f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 95f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto return ret; 96f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto} 97f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 980deb3e77025688e0650e1af672d3e42e15cd8916Kuninori Morimotoint usbhs_mod_is_host(struct usbhs_priv *priv) 99f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto{ 1000deb3e77025688e0650e1af672d3e42e15cd8916Kuninori Morimoto struct usbhs_mod *mod = usbhs_mod_get_current(priv); 101f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto struct usbhs_mod_info *info = usbhs_priv_to_modinfo(priv); 102f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 103f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto if (!mod) 104f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto return -EINVAL; 105f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 106f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto return info->mod[USBHS_HOST] == mod; 107f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto} 108f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 109f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimotostruct usbhs_mod *usbhs_mod_get_current(struct usbhs_priv *priv) 110f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto{ 111f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto struct usbhs_mod_info *info = usbhs_priv_to_modinfo(priv); 112f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 113f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto return info->curt; 114f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto} 115f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 116f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimotoint usbhs_mod_change(struct usbhs_priv *priv, int id) 117f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto{ 118f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto struct usbhs_mod_info *info = usbhs_priv_to_modinfo(priv); 119f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto struct usbhs_mod *mod = NULL; 120f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto int ret = 0; 121f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 122f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto /* id < 0 mean no current */ 123f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto switch (id) { 124f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto case USBHS_HOST: 125f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto case USBHS_GADGET: 126f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto mod = info->mod[id]; 127f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto break; 128f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto default: 129f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto ret = -EINVAL; 130f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto } 131f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto info->curt = mod; 132f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 133f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto return ret; 134f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto} 135f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 136f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimotostatic irqreturn_t usbhs_interrupt(int irq, void *data); 137f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimotoint usbhs_mod_probe(struct usbhs_priv *priv) 138f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto{ 139f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 140f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto int ret; 141f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 1422f98382dcdfe1f0048b447da35f34507ffb514dcKuninori Morimoto /* 1432f98382dcdfe1f0048b447da35f34507ffb514dcKuninori Morimoto * install host/gadget driver 1442f98382dcdfe1f0048b447da35f34507ffb514dcKuninori Morimoto */ 145034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto ret = usbhs_mod_host_probe(priv); 1462f98382dcdfe1f0048b447da35f34507ffb514dcKuninori Morimoto if (ret < 0) 1472f98382dcdfe1f0048b447da35f34507ffb514dcKuninori Morimoto return ret; 1482f98382dcdfe1f0048b447da35f34507ffb514dcKuninori Morimoto 149034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto ret = usbhs_mod_gadget_probe(priv); 150034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto if (ret < 0) 151034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto goto mod_init_host_err; 152034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 153f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto /* irq settings */ 154f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto ret = request_irq(priv->irq, usbhs_interrupt, 15553069af3fa8ba2849cd4785160690873995d4f39Shimoda, Yoshihiro priv->irqflags, dev_name(dev), priv); 1562f98382dcdfe1f0048b447da35f34507ffb514dcKuninori Morimoto if (ret) { 157f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto dev_err(dev, "irq request err\n"); 1582f98382dcdfe1f0048b447da35f34507ffb514dcKuninori Morimoto goto mod_init_gadget_err; 1592f98382dcdfe1f0048b447da35f34507ffb514dcKuninori Morimoto } 1602f98382dcdfe1f0048b447da35f34507ffb514dcKuninori Morimoto 1612f98382dcdfe1f0048b447da35f34507ffb514dcKuninori Morimoto return ret; 1622f98382dcdfe1f0048b447da35f34507ffb514dcKuninori Morimoto 1632f98382dcdfe1f0048b447da35f34507ffb514dcKuninori Morimotomod_init_gadget_err: 1642f98382dcdfe1f0048b447da35f34507ffb514dcKuninori Morimoto usbhs_mod_gadget_remove(priv); 165034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotomod_init_host_err: 166034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhs_mod_host_remove(priv); 167f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 168f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto return ret; 169f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto} 170f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 171f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimotovoid usbhs_mod_remove(struct usbhs_priv *priv) 172f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto{ 173034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhs_mod_host_remove(priv); 1742f98382dcdfe1f0048b447da35f34507ffb514dcKuninori Morimoto usbhs_mod_gadget_remove(priv); 175f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto free_irq(priv->irq, priv); 176f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto} 177f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 178f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto/* 179f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * status functions 180f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto */ 181f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimotoint usbhs_status_get_device_state(struct usbhs_irq_state *irq_state) 182f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto{ 183f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto int state = irq_state->intsts0 & DVSQ_MASK; 184f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 185f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto switch (state) { 186f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto case POWER_STATE: 187f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto case DEFAULT_STATE: 188f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto case ADDRESS_STATE: 189f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto case CONFIGURATION_STATE: 190f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto return state; 191f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto } 192f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 193f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto return -EIO; 194f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto} 195f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 196f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimotoint usbhs_status_get_ctrl_stage(struct usbhs_irq_state *irq_state) 197f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto{ 198f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto /* 199f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * return value 200f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * 201f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * IDLE_SETUP_STAGE 202f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * READ_DATA_STAGE 203f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * READ_STATUS_STAGE 204f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * WRITE_DATA_STAGE 205f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * WRITE_STATUS_STAGE 206f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * NODATA_STATUS_STAGE 207f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * SEQUENCE_ERROR 208f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto */ 209f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto return (int)irq_state->intsts0 & CTSQ_MASK; 210f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto} 211f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 212f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimotostatic void usbhs_status_get_each_irq(struct usbhs_priv *priv, 213f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto struct usbhs_irq_state *state) 214f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto{ 215f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto struct usbhs_mod *mod = usbhs_mod_get_current(priv); 216f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 217f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto state->intsts0 = usbhs_read(priv, INTSTS0); 218f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto state->intsts1 = usbhs_read(priv, INTSTS1); 219f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 220f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto /* mask */ 2215ea68d541df200d10a373c06f945f98225c2486bKuninori Morimoto if (mod) { 2225ea68d541df200d10a373c06f945f98225c2486bKuninori Morimoto state->brdysts = usbhs_read(priv, BRDYSTS); 2235ea68d541df200d10a373c06f945f98225c2486bKuninori Morimoto state->nrdysts = usbhs_read(priv, NRDYSTS); 2245ea68d541df200d10a373c06f945f98225c2486bKuninori Morimoto state->bempsts = usbhs_read(priv, BEMPSTS); 2255ea68d541df200d10a373c06f945f98225c2486bKuninori Morimoto 2265ea68d541df200d10a373c06f945f98225c2486bKuninori Morimoto state->bempsts &= mod->irq_bempsts; 2275ea68d541df200d10a373c06f945f98225c2486bKuninori Morimoto state->brdysts &= mod->irq_brdysts; 2285ea68d541df200d10a373c06f945f98225c2486bKuninori Morimoto } 229f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto} 230f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 231f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto/* 232f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * interrupt 233f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto */ 234f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto#define INTSTS0_MAGIC 0xF800 /* acknowledge magical interrupt sources */ 235f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto#define INTSTS1_MAGIC 0xA870 /* acknowledge magical interrupt sources */ 236f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimotostatic irqreturn_t usbhs_interrupt(int irq, void *data) 237f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto{ 238f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto struct usbhs_priv *priv = data; 239f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto struct usbhs_irq_state irq_state; 240f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 241f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto usbhs_status_get_each_irq(priv, &irq_state); 242f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 243f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto /* 244f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * clear interrupt 245f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * 246f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * The hardware is _very_ picky to clear interrupt bit. 247f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * Especially INTSTS0_MAGIC, INTSTS1_MAGIC value. 248f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * 249f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * see 250f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * "Operation" 251f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * - "Control Transfer (DCP)" 252f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * - Function :: VALID bit should 0 253f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto */ 254f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto usbhs_write(priv, INTSTS0, ~irq_state.intsts0 & INTSTS0_MAGIC); 255f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto usbhs_write(priv, INTSTS1, ~irq_state.intsts1 & INTSTS1_MAGIC); 256f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 257f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto usbhs_write(priv, BRDYSTS, 0); 258f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto usbhs_write(priv, NRDYSTS, 0); 259f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto usbhs_write(priv, BEMPSTS, 0); 260f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 261f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto /* 262f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * call irq callback functions 263f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * see also 264f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * usbhs_irq_setting_update 265f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto */ 26689c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto 26789c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto /* INTSTS0 */ 268b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto if (irq_state.intsts0 & VBINT) 269b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto usbhs_mod_info_call(priv, irq_vbus, priv, &irq_state); 270b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto 271f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto if (irq_state.intsts0 & DVST) 272f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto usbhs_mod_call(priv, irq_dev_state, priv, &irq_state); 273f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 274f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto if (irq_state.intsts0 & CTRT) 275f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto usbhs_mod_call(priv, irq_ctrl_stage, priv, &irq_state); 276f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 277f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto if (irq_state.intsts0 & BEMP) 278f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto usbhs_mod_call(priv, irq_empty, priv, &irq_state); 279f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 280f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto if (irq_state.intsts0 & BRDY) 281f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto usbhs_mod_call(priv, irq_ready, priv, &irq_state); 282f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 28389c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto /* INTSTS1 */ 28489c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto if (irq_state.intsts1 & ATTCH) 28589c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto usbhs_mod_call(priv, irq_attch, priv, &irq_state); 28689c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto 28789c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto if (irq_state.intsts1 & DTCH) 28889c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto usbhs_mod_call(priv, irq_dtch, priv, &irq_state); 28989c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto 29089c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto if (irq_state.intsts1 & SIGN) 29189c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto usbhs_mod_call(priv, irq_sign, priv, &irq_state); 29289c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto 29389c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto if (irq_state.intsts1 & SACK) 29489c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto usbhs_mod_call(priv, irq_sack, priv, &irq_state); 29589c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto 296f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto return IRQ_HANDLED; 297f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto} 298f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 299f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimotovoid usbhs_irq_callback_update(struct usbhs_priv *priv, struct usbhs_mod *mod) 300f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto{ 301f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto u16 intenb0 = 0; 30289c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto u16 intenb1 = 0; 303b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto struct usbhs_mod_info *info = usbhs_priv_to_modinfo(priv); 304f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 305651f5e49dd3d369711bd622f4bc72c2fa30a3cf9Kuninori Morimoto /* 306651f5e49dd3d369711bd622f4bc72c2fa30a3cf9Kuninori Morimoto * BEMPENB/BRDYENB are picky. 307651f5e49dd3d369711bd622f4bc72c2fa30a3cf9Kuninori Morimoto * below method is required 308651f5e49dd3d369711bd622f4bc72c2fa30a3cf9Kuninori Morimoto * 309651f5e49dd3d369711bd622f4bc72c2fa30a3cf9Kuninori Morimoto * - clear INTSTS0 310651f5e49dd3d369711bd622f4bc72c2fa30a3cf9Kuninori Morimoto * - update BEMPENB/BRDYENB 311651f5e49dd3d369711bd622f4bc72c2fa30a3cf9Kuninori Morimoto * - update INTSTS0 312651f5e49dd3d369711bd622f4bc72c2fa30a3cf9Kuninori Morimoto */ 313f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto usbhs_write(priv, INTENB0, 0); 31489c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto usbhs_write(priv, INTENB1, 0); 315f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 316f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto usbhs_write(priv, BEMPENB, 0); 317f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto usbhs_write(priv, BRDYENB, 0); 318f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 319f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto /* 320f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * see also 321f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * usbhs_interrupt 322f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto */ 323f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 324f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto /* 325f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * it don't enable DVSE (intenb0) here 326f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto * but "mod->irq_dev_state" will be called. 327f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto */ 328b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto if (info->irq_vbus) 329b002ff6e268b6024d6927a1ce330a14ca162b6abKuninori Morimoto intenb0 |= VBSE; 330f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 3315ea68d541df200d10a373c06f945f98225c2486bKuninori Morimoto if (mod) { 33289c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto /* 33389c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto * INTSTS0 33489c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto */ 3355ea68d541df200d10a373c06f945f98225c2486bKuninori Morimoto if (mod->irq_ctrl_stage) 3365ea68d541df200d10a373c06f945f98225c2486bKuninori Morimoto intenb0 |= CTRE; 337f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 3385ea68d541df200d10a373c06f945f98225c2486bKuninori Morimoto if (mod->irq_empty && mod->irq_bempsts) { 3395ea68d541df200d10a373c06f945f98225c2486bKuninori Morimoto usbhs_write(priv, BEMPENB, mod->irq_bempsts); 3405ea68d541df200d10a373c06f945f98225c2486bKuninori Morimoto intenb0 |= BEMPE; 3415ea68d541df200d10a373c06f945f98225c2486bKuninori Morimoto } 342f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 3435ea68d541df200d10a373c06f945f98225c2486bKuninori Morimoto if (mod->irq_ready && mod->irq_brdysts) { 3445ea68d541df200d10a373c06f945f98225c2486bKuninori Morimoto usbhs_write(priv, BRDYENB, mod->irq_brdysts); 3455ea68d541df200d10a373c06f945f98225c2486bKuninori Morimoto intenb0 |= BRDYE; 3465ea68d541df200d10a373c06f945f98225c2486bKuninori Morimoto } 34789c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto 34889c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto /* 34989c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto * INTSTS1 35089c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto */ 35189c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto if (mod->irq_attch) 35289c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto intenb1 |= ATTCHE; 35389c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto 354b95eb7476e7224baae34f67ae9a09042521e97ffKuninori Morimoto if (mod->irq_dtch) 35589c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto intenb1 |= DTCHE; 35689c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto 35789c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto if (mod->irq_sign) 35889c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto intenb1 |= SIGNE; 35989c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto 36089c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto if (mod->irq_sack) 36189c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto intenb1 |= SACKE; 362f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto } 363f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto 364651f5e49dd3d369711bd622f4bc72c2fa30a3cf9Kuninori Morimoto if (intenb0) 365651f5e49dd3d369711bd622f4bc72c2fa30a3cf9Kuninori Morimoto usbhs_write(priv, INTENB0, intenb0); 36689c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto 36789c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto if (intenb1) 36889c1d2e7b5993db33805b42e3675289920812f6fKuninori Morimoto usbhs_write(priv, INTENB1, intenb1); 369f1407d5c66240b33d11a7f1a41d55ccf6a9d7647Kuninori Morimoto} 370