@@ -146,6 +146,9 @@ int snd_hdac_bus_send_cmd(struct hdac_bus *bus, unsigned int val)
146146{
147147 unsigned int addr = azx_command_addr (val );
148148 unsigned int wp , rp ;
149+ unsigned long timeout ;
150+ unsigned int rirb_wp ;
151+ int i = 0 ;
149152
150153 spin_lock_irq (& bus -> reg_lock );
151154
@@ -172,6 +175,42 @@ int snd_hdac_bus_send_cmd(struct hdac_bus *bus, unsigned int val)
172175 bus -> corb .buf [wp ] = cpu_to_le32 (val );
173176 snd_hdac_chip_writew (bus , CORBWP , wp );
174177
178+ if (bus -> cmd_resend ) {
179+ timeout = jiffies + msecs_to_jiffies (1000 );
180+ udelay (80 );
181+ rirb_wp = snd_hdac_chip_readw (bus , RIRBWP );
182+ while (rirb_wp == bus -> rirb .wp ) {
183+ udelay (80 );
184+ rirb_wp = snd_hdac_chip_readw (bus , RIRBWP );
185+ if (rirb_wp != bus -> rirb .wp )
186+ break ;
187+ if (i > 5 )
188+ break ;
189+ if (time_after (jiffies , timeout ))
190+ break ;
191+
192+ /* add command to corb */
193+ wp = snd_hdac_chip_readw (bus , CORBWP );
194+ if (wp == 0xffff ) {
195+ /* something wrong, controller likely turned to D3 */
196+ spin_unlock_irq (& bus -> reg_lock );
197+ return - EIO ;
198+ }
199+ wp ++ ;
200+ wp %= AZX_MAX_CORB_ENTRIES ;
201+
202+ rp = snd_hdac_chip_readw (bus , CORBRP );
203+ if (wp == rp ) {
204+ /* oops, it's full */
205+ spin_unlock_irq (& bus -> reg_lock );
206+ return - EAGAIN ;
207+ }
208+ bus -> corb .buf [wp ] = cpu_to_le32 (val );
209+ snd_hdac_chip_writew (bus , CORBWP , wp );
210+ i ++ ;
211+ }
212+ }
213+
175214 spin_unlock_irq (& bus -> reg_lock );
176215
177216 return 0 ;
0 commit comments